@oxyhq/services 23.2.0 → 24.0.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.
- package/android/src/main/java/so/oxy/identity/OxyIdentityStore.kt +21 -127
- package/android/src/main/java/so/oxy/session/OxyBackgroundSession.kt +184 -0
- package/android/src/main/java/so/oxy/session/OxyBackgroundSessionApi.kt +162 -0
- package/android/src/main/java/so/oxy/session/OxyBackgroundSessionModule.kt +101 -0
- package/android/src/main/java/so/oxy/session/OxyBackgroundSessionStore.kt +170 -0
- package/android/src/main/java/so/oxy/session/OxyBackgroundToken.kt +61 -0
- package/android/src/main/java/so/oxy/storage/OxyEncryptedPrefs.kt +241 -0
- package/expo-module.config.json +4 -1
- package/lib/commonjs/ui/components/OxyProvider.js +3 -1
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/ProfileButton.js +1 -1
- package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +3 -1
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/logo/LogoText.js +4 -4
- package/lib/commonjs/ui/components/logo/LogoText.js.map +1 -1
- package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js +2 -2
- package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +13 -0
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +2 -3
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ChangeAvatarScreen.js +2 -3
- package/lib/commonjs/ui/screens/ChangeAvatarScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/EditProfileScreen.js +2 -3
- package/lib/commonjs/ui/screens/EditProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +3 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ManageAccountScreen.js +1 -1
- package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +2 -2
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +8 -9
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/UserListScreen.js +2 -3
- package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +1 -1
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +2 -3
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +1 -1
- package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/session/backgroundSession.js +233 -0
- package/lib/commonjs/ui/session/backgroundSession.js.map +1 -0
- package/lib/commonjs/ui/session/index.js +7 -0
- package/lib/commonjs/ui/session/index.js.map +1 -1
- package/lib/commonjs/ui/session/useBackgroundSessionSync.js +82 -0
- package/lib/commonjs/ui/session/useBackgroundSessionSync.js.map +1 -0
- package/lib/commonjs/ui/utils/userUtils.js +31 -22
- package/lib/commonjs/ui/utils/userUtils.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +3 -1
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/ProfileButton.js +2 -2
- package/lib/module/ui/components/ProfileButton.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +3 -1
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/logo/LogoText.js +4 -4
- package/lib/module/ui/components/logo/LogoText.js.map +1 -1
- package/lib/module/ui/components/payment/PaymentSummaryStep.js +2 -2
- package/lib/module/ui/components/payment/PaymentSummaryStep.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +14 -1
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +2 -3
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/ChangeAvatarScreen.js +3 -4
- package/lib/module/ui/screens/ChangeAvatarScreen.js.map +1 -1
- package/lib/module/ui/screens/EditProfileScreen.js +3 -4
- package/lib/module/ui/screens/EditProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +3 -1
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/ManageAccountScreen.js +2 -2
- package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +2 -2
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/PrivacySettingsScreen.js +9 -10
- package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +1 -1
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/UserListScreen.js +2 -3
- package/lib/module/ui/screens/UserListScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustCenterScreen.js +1 -1
- package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +2 -3
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustRewardsScreen.js +1 -1
- package/lib/module/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
- package/lib/module/ui/session/backgroundSession.js +227 -0
- package/lib/module/ui/session/backgroundSession.js.map +1 -0
- package/lib/module/ui/session/index.js +1 -0
- package/lib/module/ui/session/index.js.map +1 -1
- package/lib/module/ui/session/useBackgroundSessionSync.js +77 -0
- package/lib/module/ui/session/useBackgroundSessionSync.js.map +1 -0
- package/lib/module/ui/utils/userUtils.js +31 -22
- package/lib/module/ui/utils/userUtils.js.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +22 -0
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts +1 -1
- package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts +42 -0
- package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/session/index.d.ts +1 -0
- package/lib/typescript/commonjs/ui/session/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts +23 -0
- package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/types/navigation.d.ts +7 -0
- package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/userUtils.d.ts +7 -12
- package/lib/typescript/commonjs/ui/utils/userUtils.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +22 -0
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/trustTier.d.ts +1 -1
- package/lib/typescript/module/ui/screens/trust/trustTier.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/backgroundSession.d.ts +42 -0
- package/lib/typescript/module/ui/session/backgroundSession.d.ts.map +1 -0
- package/lib/typescript/module/ui/session/index.d.ts +1 -0
- package/lib/typescript/module/ui/session/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts +23 -0
- package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts.map +1 -0
- package/lib/typescript/module/ui/types/navigation.d.ts +7 -0
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/userUtils.d.ts +7 -12
- package/lib/typescript/module/ui/utils/userUtils.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/ui/components/OxyProvider.tsx +2 -0
- package/src/ui/components/ProfileButton.tsx +5 -2
- package/src/ui/components/internal/PinInput.tsx +1 -0
- package/src/ui/components/logo/LogoText.tsx +4 -4
- package/src/ui/components/payment/PaymentSummaryStep.tsx +2 -2
- package/src/ui/context/OxyContext.tsx +14 -0
- package/src/ui/context/oxyContextTypes.ts +22 -0
- package/src/ui/screens/AccountSettingsScreen.tsx +4 -4
- package/src/ui/screens/ChangeAvatarScreen.tsx +6 -3
- package/src/ui/screens/EditProfileScreen.tsx +6 -3
- package/src/ui/screens/FeedbackScreen.tsx +1 -0
- package/src/ui/screens/ManageAccountScreen.tsx +8 -1
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +2 -2
- package/src/ui/screens/PrivacySettingsScreen.tsx +13 -11
- package/src/ui/screens/ProfileScreen.tsx +3 -1
- package/src/ui/screens/UserListScreen.tsx +2 -2
- package/src/ui/screens/trust/TrustCenterScreen.tsx +2 -2
- package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +3 -3
- package/src/ui/screens/trust/TrustRewardsScreen.tsx +1 -1
- package/src/ui/screens/trust/TrustRulesScreen.tsx +1 -1
- package/src/ui/screens/trust/trustTier.ts +1 -1
- package/src/ui/session/__tests__/backgroundSession.test.ts +337 -0
- package/src/ui/session/backgroundSession.ts +268 -0
- package/src/ui/session/index.ts +1 -0
- package/src/ui/session/useBackgroundSessionSync.ts +93 -0
- package/src/ui/types/navigation.ts +7 -0
- package/src/ui/utils/userUtils.ts +34 -20
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps the native background credential in step with the session, so an app
|
|
3
|
+
* enables background authentication with one prop and writes no session code of
|
|
4
|
+
* its own.
|
|
5
|
+
*
|
|
6
|
+
* See `./backgroundSession` for what the credential is and why it is separate
|
|
7
|
+
* from the rotating device secret.
|
|
8
|
+
*/
|
|
9
|
+
import { useEffect } from 'react';
|
|
10
|
+
import { AppState } from 'react-native';
|
|
11
|
+
import type { OxyServices } from '@oxyhq/core';
|
|
12
|
+
import {
|
|
13
|
+
clearBackgroundSession,
|
|
14
|
+
isBackgroundSessionSupported,
|
|
15
|
+
syncBackgroundSession,
|
|
16
|
+
} from './backgroundSession';
|
|
17
|
+
|
|
18
|
+
export interface UseBackgroundSessionSyncInput {
|
|
19
|
+
/** `OxyProviderProps.backgroundSession`. */
|
|
20
|
+
enabled: boolean;
|
|
21
|
+
oxyServices: OxyServices;
|
|
22
|
+
/** The signed-in account, or `null` when signed out. */
|
|
23
|
+
userId: string | null;
|
|
24
|
+
/** Whether a bearer is available yet — provisioning needs one. */
|
|
25
|
+
canUsePrivateApi: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* An effect is the right shape here, unusually for this codebase: the work is a
|
|
30
|
+
* side effect on native storage, and it has to react both to an identity change
|
|
31
|
+
* (a value) and to the app being foregrounded (a subscription). There is no
|
|
32
|
+
* derived-state or React Query formulation of "write a credential to the
|
|
33
|
+
* keystore when the user changes or the app comes back".
|
|
34
|
+
*
|
|
35
|
+
* Re-runs on identity change, which is what makes sign-out and account switching
|
|
36
|
+
* work: `syncBackgroundSession` clears a credential belonging to anyone other
|
|
37
|
+
* than `userId` before it does any network work.
|
|
38
|
+
*/
|
|
39
|
+
export function useBackgroundSessionSync({
|
|
40
|
+
enabled,
|
|
41
|
+
oxyServices,
|
|
42
|
+
userId,
|
|
43
|
+
canUsePrivateApi,
|
|
44
|
+
}: UseBackgroundSessionSyncInput): void {
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!isBackgroundSessionSupported()) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!enabled) {
|
|
51
|
+
// An app that turns the feature OFF must not leave a live credential at
|
|
52
|
+
// rest for the rest of its 30-day lifetime. The cost is one local store
|
|
53
|
+
// open per launch on Android apps that never use the feature, which is
|
|
54
|
+
// accepted deliberately: correct revocation is worth more than skipping a
|
|
55
|
+
// memoized keystore open.
|
|
56
|
+
void clearBackgroundSession();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// A run that is superseded (unmount, or another identity change) must not
|
|
61
|
+
// write the credential it was about to write.
|
|
62
|
+
let current = true;
|
|
63
|
+
// Deliberately NOT caught. `syncBackgroundSession` already handles every
|
|
64
|
+
// runtime failure internally and throws for exactly one thing: an installed
|
|
65
|
+
// `@oxyhq/core` too old to provision. That is a dependency mistake which must
|
|
66
|
+
// surface, so it is allowed to reject — adding a `.catch()` here would put it
|
|
67
|
+
// back behind the silence it was moved out of.
|
|
68
|
+
const run = () => {
|
|
69
|
+
void syncBackgroundSession({
|
|
70
|
+
oxyServices,
|
|
71
|
+
userId,
|
|
72
|
+
canUsePrivateApi,
|
|
73
|
+
isCurrent: () => current,
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
run();
|
|
78
|
+
const subscription = AppState.addEventListener('change', (state) => {
|
|
79
|
+
if (state === 'active') {
|
|
80
|
+
run();
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return () => {
|
|
85
|
+
current = false;
|
|
86
|
+
subscription.remove();
|
|
87
|
+
// Deliberately NOT clearing here. Unmount is the app closing, which is
|
|
88
|
+
// precisely when the credential has to survive — clearing on teardown
|
|
89
|
+
// would defeat the entire feature. Revocation happens on sign-out (via a
|
|
90
|
+
// `userId` of null), on the server, or when the credential expires.
|
|
91
|
+
};
|
|
92
|
+
}, [enabled, oxyServices, userId, canUsePrivateApi]);
|
|
93
|
+
}
|
|
@@ -136,4 +136,11 @@ export interface OxyProviderProps {
|
|
|
136
136
|
* @default 'off'
|
|
137
137
|
*/
|
|
138
138
|
requireAuth?: 'off' | 'soft' | 'hard';
|
|
139
|
+
/**
|
|
140
|
+
* When true, provisions a non-rotating background credential for native code
|
|
141
|
+
* (Android widgets) that runs without a JS runtime. Android-only today; inert
|
|
142
|
+
* on web and iOS.
|
|
143
|
+
* @default false
|
|
144
|
+
*/
|
|
145
|
+
backgroundSession?: boolean;
|
|
139
146
|
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* User display name and date formatting utilities.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Display-name helpers follow the API contract: prefer `name.displayName` when
|
|
5
|
+
* present, otherwise fall back to the normalized handle. The legacy
|
|
6
|
+
* `getAccountDisplayName` chain is only used as a last resort for local
|
|
7
|
+
* account-switcher surfaces without a handle.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
import {
|
|
10
11
|
getAccountDisplayName as coreGetAccountDisplayName,
|
|
12
|
+
getNormalizedUserHandle,
|
|
11
13
|
type DisplayNameUserShape,
|
|
12
14
|
} from '@oxyhq/core';
|
|
13
15
|
|
|
@@ -31,44 +33,56 @@ export const formatDate = (dateString: string | undefined | null | Date): string
|
|
|
31
33
|
}
|
|
32
34
|
};
|
|
33
35
|
|
|
36
|
+
function readDisplayName(user: DisplayNameUserShape | null | undefined): string {
|
|
37
|
+
const name = user?.name;
|
|
38
|
+
if (!name || typeof name !== 'object') return '';
|
|
39
|
+
return typeof name.displayName === 'string' ? name.displayName.trim() : '';
|
|
40
|
+
}
|
|
41
|
+
|
|
34
42
|
/**
|
|
35
43
|
* Gets a display name from user data.
|
|
36
44
|
*
|
|
37
|
-
* Prefers
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* @param user - User-like object with optional name/username/publicKey
|
|
41
|
-
* @param locale - Optional locale for the final fallback label
|
|
45
|
+
* Prefers API `name.displayName`, then the normalized handle, then the local
|
|
46
|
+
* account-switcher fallback chain.
|
|
42
47
|
*/
|
|
43
48
|
export const getDisplayName = (
|
|
44
49
|
user: DisplayNameUserShape | null | undefined,
|
|
45
50
|
locale?: string,
|
|
46
|
-
): string =>
|
|
51
|
+
): string => {
|
|
52
|
+
const displayName = readDisplayName(user);
|
|
53
|
+
if (displayName) return displayName;
|
|
54
|
+
|
|
55
|
+
const handle = getNormalizedUserHandle(user);
|
|
56
|
+
if (handle) return handle;
|
|
57
|
+
|
|
58
|
+
return coreGetAccountDisplayName(user, locale);
|
|
59
|
+
};
|
|
47
60
|
|
|
48
61
|
/**
|
|
49
|
-
* Gets a short display name (first
|
|
50
|
-
*
|
|
51
|
-
* Used for compact UI (e.g. greetings). Falls back to the full display name
|
|
52
|
-
* helper, which also handles publicKey-only accounts.
|
|
62
|
+
* Gets a short display name (first token) for compact UI.
|
|
53
63
|
*/
|
|
54
64
|
export const getShortDisplayName = (
|
|
55
65
|
user: DisplayNameUserShape | null | undefined,
|
|
56
66
|
locale?: string,
|
|
57
67
|
): string => {
|
|
58
|
-
|
|
68
|
+
const displayName = readDisplayName(user);
|
|
69
|
+
if (displayName) {
|
|
70
|
+
const firstToken = displayName.split(/\s+/).find(Boolean);
|
|
71
|
+
if (firstToken) return firstToken;
|
|
72
|
+
}
|
|
59
73
|
|
|
60
|
-
const name = user
|
|
74
|
+
const name = user?.name;
|
|
61
75
|
if (name && typeof name === 'object') {
|
|
62
76
|
const first = typeof name.first === 'string' ? name.first.trim() : '';
|
|
63
|
-
if (first) return first;
|
|
77
|
+
if (first) return first.split(/\s+/)[0] ?? first;
|
|
64
78
|
const full = typeof name.full === 'string' ? name.full.trim() : '';
|
|
65
|
-
if (full) return full.split(
|
|
79
|
+
if (full) return full.split(/\s+/)[0] ?? full;
|
|
66
80
|
} else if (typeof name === 'string' && name.trim()) {
|
|
67
|
-
return name.trim().split(
|
|
81
|
+
return name.trim().split(/\s+/)[0] ?? name.trim();
|
|
68
82
|
}
|
|
69
83
|
|
|
70
|
-
|
|
84
|
+
const handle = getNormalizedUserHandle(user);
|
|
85
|
+
if (handle) return handle;
|
|
71
86
|
|
|
72
|
-
// Defer to the canonical helper for publicKey/unnamed fallbacks.
|
|
73
87
|
return coreGetAccountDisplayName(user, locale);
|
|
74
88
|
};
|