@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/FeedbackScreen.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AAyC3D,QAAA,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"FeedbackScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/FeedbackScreen.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AAyC3D,QAAA,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAuqB7C,CAAC;AAwBF,eAAe,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ManageAccountScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/ManageAccountScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ManageAccountScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/ManageAccountScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAqB/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AAqD3D;;;;;;;GAOG;AACH,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAg1BlD,CAAC;AAYF,eAAe,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrivacySettingsScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/PrivacySettingsScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;;
|
|
1
|
+
{"version":3,"file":"PrivacySettingsScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/PrivacySettingsScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;;AAma3D,wBAAiD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/ProfileScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AAe3D,UAAU,kBAAmB,SAAQ,eAAe;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAOD,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"ProfileScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/ProfileScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AAe3D,UAAU,kBAAmB,SAAQ,eAAe;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAOD,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAoS/C,CAAC;AAuCF,eAAe,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trustTier.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/screens/trust/trustTier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"trustTier.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/screens/trust/trustTier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,MAAM,CAAC;AAWjF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAEvE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { OxyServices } from '@oxyhq/core';
|
|
2
|
+
/** Whether this platform/app can hold a background credential at all. */
|
|
3
|
+
export declare function isBackgroundSessionSupported(): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Drop the stored credential. No-op where unsupported, and never throws.
|
|
6
|
+
*
|
|
7
|
+
* Called on sign-out and BEFORE an account switch's network work, so the window
|
|
8
|
+
* in which background code could still serve the previous account is as short as
|
|
9
|
+
* one local write.
|
|
10
|
+
*/
|
|
11
|
+
export declare function clearBackgroundSession(): Promise<void>;
|
|
12
|
+
export interface BackgroundSessionSyncInput {
|
|
13
|
+
oxyServices: OxyServices;
|
|
14
|
+
/** The signed-in account, or `null` when signed out. */
|
|
15
|
+
userId: string | null;
|
|
16
|
+
/** Whether a bearer is available yet — provisioning requires one. */
|
|
17
|
+
canUsePrivateApi: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Whether this run is still the current one. A run that loses its relevance
|
|
20
|
+
* mid-flight (unmount, or another identity change) must not write the
|
|
21
|
+
* credential it was about to write.
|
|
22
|
+
*/
|
|
23
|
+
isCurrent: () => boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Bring the native credential in line with the session JS currently holds.
|
|
27
|
+
*
|
|
28
|
+
* Ordering is the load-bearing part: a credential belonging to a DIFFERENT
|
|
29
|
+
* account is cleared before any network call, so a crash mid-provision leaves
|
|
30
|
+
* background code signed out rather than serving the previous account's data
|
|
31
|
+
* under the new account's name. The server enforces the same rule independently
|
|
32
|
+
* (a mint is re-authorized against the live device session, and against its ACTIVE
|
|
33
|
+
* account), so this is the fast local half of a belt-and-braces pair, not the only
|
|
34
|
+
* guard.
|
|
35
|
+
*
|
|
36
|
+
* Throws for exactly one thing — a `@oxyhq/core` too old to provision (see
|
|
37
|
+
* {@link assertProvisioningAvailable}). Every other failure is caught and logged:
|
|
38
|
+
* a background credential is an enhancement, and failing to provision one must
|
|
39
|
+
* not disturb the session that is working.
|
|
40
|
+
*/
|
|
41
|
+
export declare function syncBackgroundSession(input: BackgroundSessionSyncInput): Promise<void>;
|
|
42
|
+
//# sourceMappingURL=backgroundSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backgroundSession.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/backgroundSession.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgE/C,yEAAyE;AACzE,wBAAgB,4BAA4B,IAAI,OAAO,CAEtD;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAa5D;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,WAAW,CAAC;IACzB,wDAAwD;IACxD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,qEAAqE;IACrE,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC;CAC1B;AA8BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAqF5F"}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
export { createSessionClient } from './createSessionClient.js';
|
|
14
14
|
export { createTokenTransport } from './tokenTransport.js';
|
|
15
15
|
export { createPlatformAuthStateStore } from './authStore.js';
|
|
16
|
+
export { useBackgroundSessionSync } from './useBackgroundSessionSync.js';
|
|
16
17
|
export { createIdentitySessionBinding, IdentityBoundSessionError } from './identityBinding.js';
|
|
17
18
|
export type { IdentitySessionBinding } from './identityBinding.js';
|
|
18
19
|
export { createSessionClientHost, accountIdsOf, activeSessionIdOf, activeUserOf, deviceStateToClientSessions, } from '@oxyhq/core';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAkB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAa,CAAC;AAC3D,OAAO,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,MAAM,sBAAmB,CAAC;AAC5F,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAmB,CAAC;AAChE,OAAO,EACL,uBAAuB,EACvB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAkB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAa,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA4B,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,MAAM,sBAAmB,CAAC;AAC5F,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAmB,CAAC;AAChE,OAAO,EACL,uBAAuB,EACvB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { OxyServices } from '@oxyhq/core';
|
|
2
|
+
export interface UseBackgroundSessionSyncInput {
|
|
3
|
+
/** `OxyProviderProps.backgroundSession`. */
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
oxyServices: OxyServices;
|
|
6
|
+
/** The signed-in account, or `null` when signed out. */
|
|
7
|
+
userId: string | null;
|
|
8
|
+
/** Whether a bearer is available yet — provisioning needs one. */
|
|
9
|
+
canUsePrivateApi: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* An effect is the right shape here, unusually for this codebase: the work is a
|
|
13
|
+
* side effect on native storage, and it has to react both to an identity change
|
|
14
|
+
* (a value) and to the app being foregrounded (a subscription). There is no
|
|
15
|
+
* derived-state or React Query formulation of "write a credential to the
|
|
16
|
+
* keystore when the user changes or the app comes back".
|
|
17
|
+
*
|
|
18
|
+
* Re-runs on identity change, which is what makes sign-out and account switching
|
|
19
|
+
* work: `syncBackgroundSession` clears a credential belonging to anyone other
|
|
20
|
+
* than `userId` before it does any network work.
|
|
21
|
+
*/
|
|
22
|
+
export declare function useBackgroundSessionSync({ enabled, oxyServices, userId, canUsePrivateApi, }: UseBackgroundSessionSyncInput): void;
|
|
23
|
+
//# sourceMappingURL=useBackgroundSessionSync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBackgroundSessionSync.d.ts","sourceRoot":"","sources":["../../../../../src/ui/session/useBackgroundSessionSync.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO/C,MAAM,WAAW,6BAA6B;IAC5C,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,wDAAwD;IACxD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kEAAkE;IAClE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,WAAW,EACX,MAAM,EACN,gBAAgB,GACjB,EAAE,6BAA6B,GAAG,IAAI,CAiDtC"}
|
|
@@ -116,5 +116,12 @@ export interface OxyProviderProps {
|
|
|
116
116
|
* @default 'off'
|
|
117
117
|
*/
|
|
118
118
|
requireAuth?: 'off' | 'soft' | 'hard';
|
|
119
|
+
/**
|
|
120
|
+
* When true, provisions a non-rotating background credential for native code
|
|
121
|
+
* (Android widgets) that runs without a JS runtime. Android-only today; inert
|
|
122
|
+
* on web and iOS.
|
|
123
|
+
* @default false
|
|
124
|
+
*/
|
|
125
|
+
backgroundSession?: boolean;
|
|
119
126
|
}
|
|
120
127
|
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../../src/ui/types/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAgB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAE5B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACxE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGrC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAGlC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAGjE,aAAa,CAAC,EAAE,SAAS,CAAC;IAG1B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IAMtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../../src/ui/types/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAgB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAE5B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACxE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGrC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAGlC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAGjE,aAAa,CAAC,EAAE,SAAS,CAAC;IAG1B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IAMtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B"}
|
|
@@ -1,9 +1,10 @@
|
|
|
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
|
import { type DisplayNameUserShape } from '@oxyhq/core';
|
|
9
10
|
/**
|
|
@@ -13,18 +14,12 @@ export declare const formatDate: (dateString: string | undefined | null | Date)
|
|
|
13
14
|
/**
|
|
14
15
|
* Gets a display name from user data.
|
|
15
16
|
*
|
|
16
|
-
* Prefers
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* @param user - User-like object with optional name/username/publicKey
|
|
20
|
-
* @param locale - Optional locale for the final fallback label
|
|
17
|
+
* Prefers API `name.displayName`, then the normalized handle, then the local
|
|
18
|
+
* account-switcher fallback chain.
|
|
21
19
|
*/
|
|
22
20
|
export declare const getDisplayName: (user: DisplayNameUserShape | null | undefined, locale?: string) => string;
|
|
23
21
|
/**
|
|
24
|
-
* Gets a short display name (first
|
|
25
|
-
*
|
|
26
|
-
* Used for compact UI (e.g. greetings). Falls back to the full display name
|
|
27
|
-
* helper, which also handles publicKey-only accounts.
|
|
22
|
+
* Gets a short display name (first token) for compact UI.
|
|
28
23
|
*/
|
|
29
24
|
export declare const getShortDisplayName: (user: DisplayNameUserShape | null | undefined, locale?: string) => string;
|
|
30
25
|
//# sourceMappingURL=userUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userUtils.d.ts","sourceRoot":"","sources":["../../../../../src/ui/utils/userUtils.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"userUtils.d.ts","sourceRoot":"","sources":["../../../../../src/ui/utils/userUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,YAAY,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,KAAG,MAezE,CAAC;AAQF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,oBAAoB,GAAG,IAAI,GAAG,SAAS,EAC7C,SAAS,MAAM,KACd,MAQF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC9B,MAAM,oBAAoB,GAAG,IAAI,GAAG,SAAS,EAC7C,SAAS,MAAM,KACd,MAqBF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/services",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "24.0.0",
|
|
4
4
|
"description": "OxyHQ Expo/React Native SDK — UI components, screens, and native features",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -138,8 +138,8 @@
|
|
|
138
138
|
}
|
|
139
139
|
},
|
|
140
140
|
"dependencies": {
|
|
141
|
-
"@oxyhq/contracts": "0.
|
|
142
|
-
"@oxyhq/core": "^
|
|
141
|
+
"@oxyhq/contracts": "0.20.0",
|
|
142
|
+
"@oxyhq/core": "^15.0.0",
|
|
143
143
|
"@simplewebauthn/browser": "^13.3.0",
|
|
144
144
|
"color": "^4.2.3"
|
|
145
145
|
},
|
|
@@ -148,7 +148,7 @@
|
|
|
148
148
|
"@commitlint/cli": "^21.2.1",
|
|
149
149
|
"@commitlint/config-conventional": "^21.2.0",
|
|
150
150
|
"@expo/vector-icons": "^15.0.3",
|
|
151
|
-
"@oxyhq/core": "
|
|
151
|
+
"@oxyhq/core": "15.0.0",
|
|
152
152
|
"@react-native-async-storage/async-storage": "^2.0.0",
|
|
153
153
|
"@react-native-community/netinfo": "^11.4.1",
|
|
154
154
|
"@react-native/babel-preset": "^0.86.0",
|
|
@@ -190,7 +190,7 @@
|
|
|
190
190
|
"peerDependencies": {
|
|
191
191
|
"@expo/vector-icons": "^15.0.3",
|
|
192
192
|
"@oxyhq/bloom": ">=0.59.0",
|
|
193
|
-
"@oxyhq/core": "^
|
|
193
|
+
"@oxyhq/core": "^15.0.0",
|
|
194
194
|
"@react-native-async-storage/async-storage": "^2.0.0",
|
|
195
195
|
"@react-native-community/netinfo": ">=11.4.1",
|
|
196
196
|
"@tanstack/query-async-storage-persister": "^5.101",
|
|
@@ -96,6 +96,7 @@ const OxyProvider: FC<OxyProviderProps> = ({
|
|
|
96
96
|
webAuthMode = 'popup',
|
|
97
97
|
queryClient: providedQueryClient,
|
|
98
98
|
requireAuth = 'off',
|
|
99
|
+
backgroundSession = false,
|
|
99
100
|
}) => {
|
|
100
101
|
|
|
101
102
|
// Dynamic KeyboardProvider for native. Uses variable indirection
|
|
@@ -293,6 +294,7 @@ const OxyProvider: FC<OxyProviderProps> = ({
|
|
|
293
294
|
clientId={clientId}
|
|
294
295
|
sessionMode={sessionMode}
|
|
295
296
|
webAuthMode={webAuthMode}
|
|
297
|
+
backgroundSession={backgroundSession}
|
|
296
298
|
onAuthStateChange={onAuthStateChange as OxyContextProviderProps['onAuthStateChange']}
|
|
297
299
|
>
|
|
298
300
|
<SurfaceProvider>
|
|
@@ -13,7 +13,7 @@ import { Avatar } from '@oxyhq/bloom/avatar';
|
|
|
13
13
|
import * as Skeleton from '@oxyhq/bloom/skeleton';
|
|
14
14
|
import { Text } from '@oxyhq/bloom/typography';
|
|
15
15
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
16
|
-
import { getAccountDisplayName, getAccountFallbackHandle } from '@oxyhq/core';
|
|
16
|
+
import { getAccountDisplayName, getAccountFallbackHandle, getNormalizedUserHandle } from '@oxyhq/core';
|
|
17
17
|
import { useAuth } from '../hooks/useAuth';
|
|
18
18
|
import { useOxy } from '../context/OxyContext';
|
|
19
19
|
import { useI18n } from '../hooks/useI18n';
|
|
@@ -201,7 +201,10 @@ const ProfileButton: React.FC<ProfileButtonProps> = ({
|
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
// ── Signed in: avatar + identity + chevron. ─────────────────────────────
|
|
204
|
-
const displayName =
|
|
204
|
+
const displayName =
|
|
205
|
+
user?.name?.displayName ??
|
|
206
|
+
getNormalizedUserHandle(user) ??
|
|
207
|
+
getAccountDisplayName(null, locale);
|
|
205
208
|
const handle = getAccountFallbackHandle(user);
|
|
206
209
|
const handleLine = handle ? `@${handle}` : null;
|
|
207
210
|
|
|
@@ -64,6 +64,7 @@ const PinInput = forwardRef<PinInputHandle, PinInputProps>(({ value, onChange, l
|
|
|
64
64
|
<View style={styles.pinContainer}>
|
|
65
65
|
{Array.from({ length }).map((_, idx) => (
|
|
66
66
|
<TextInput
|
|
67
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: fixed-position PIN cells, order never changes
|
|
67
68
|
key={`pin-input-${idx}`}
|
|
68
69
|
ref={(ref) => { inputs.current[idx] = ref; }}
|
|
69
70
|
style={[
|
|
@@ -55,13 +55,13 @@ export const LogoText: React.FC<LogoTextProps> = ({
|
|
|
55
55
|
return (
|
|
56
56
|
<Svg viewBox={`0 0 ${VIEW_BOX_WIDTH} ${VIEW_BOX_HEIGHT}`} width={width} height={height} style={style}>
|
|
57
57
|
<G>
|
|
58
|
-
{OUTER_PATHS.map((d
|
|
59
|
-
<Path key={
|
|
58
|
+
{OUTER_PATHS.map((d) => (
|
|
59
|
+
<Path key={d} d={d} fill={resolvedColor} />
|
|
60
60
|
))}
|
|
61
61
|
</G>
|
|
62
62
|
<G transform="translate(10.316 2.495)">
|
|
63
|
-
{INNER_LETTER_PATHS.map((d
|
|
64
|
-
<Path key={
|
|
63
|
+
{INNER_LETTER_PATHS.map((d) => (
|
|
64
|
+
<Path key={d} d={d} fill={resolvedLetterColor} />
|
|
65
65
|
))}
|
|
66
66
|
</G>
|
|
67
67
|
</Svg>
|
|
@@ -85,9 +85,9 @@ const PaymentSummaryStep: React.FC<PaymentSummaryStepProps> = ({
|
|
|
85
85
|
<>
|
|
86
86
|
<View style={styles.summaryCardItems}>
|
|
87
87
|
<SettingsListGroup>
|
|
88
|
-
{paymentItems.map((item
|
|
88
|
+
{paymentItems.map((item) => (
|
|
89
89
|
<SettingsListItem
|
|
90
|
-
key={
|
|
90
|
+
key={`${item.type}-${item.name}-${item.price}-${item.period ?? ''}`}
|
|
91
91
|
icon={<Ionicons name={getItemTypeIcon(item.type)} size={20} color={colors.primary} />}
|
|
92
92
|
title={`${item.type === 'product' && item.quantity ? `${item.quantity} \u00d7 ` : ''}${item.name}${item.type === 'subscription' && item.period ? ` (${item.period})` : ''}`}
|
|
93
93
|
description={item.description || `${item.currency ? (CURRENCY_SYMBOLS[item.currency.toUpperCase()] || item.currency) : currencySymbol} ${item.price * (item.quantity ?? 1)}`}
|
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
activeUserOf,
|
|
71
71
|
accountIdsOf,
|
|
72
72
|
IdentityBoundSessionError,
|
|
73
|
+
useBackgroundSessionSync,
|
|
73
74
|
type IdentitySessionBinding,
|
|
74
75
|
} from '../session';
|
|
75
76
|
import type {
|
|
@@ -103,6 +104,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
103
104
|
clientId: clientIdProp,
|
|
104
105
|
sessionMode = 'account',
|
|
105
106
|
webAuthMode = 'popup',
|
|
107
|
+
backgroundSession = false,
|
|
106
108
|
onAuthStateChange,
|
|
107
109
|
onError,
|
|
108
110
|
}) => {
|
|
@@ -1195,6 +1197,18 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
1195
1197
|
const canUsePrivateApi = authResolved && isAuthenticated && tokenReady && hasAccessToken;
|
|
1196
1198
|
const isPrivateApiPending = !authResolved || (isAuthenticated && (!tokenReady || !hasAccessToken));
|
|
1197
1199
|
|
|
1200
|
+
// Keep the native background credential in step with this session, so native
|
|
1201
|
+
// background code (a widget worker) can authenticate with no JS runtime. Inert
|
|
1202
|
+
// unless the app opted in. Placed AFTER `canUsePrivateApi` because provisioning
|
|
1203
|
+
// needs a bearer, and keyed on the signed-in account so a sign-out or an
|
|
1204
|
+
// account switch revokes the credential before anything else happens.
|
|
1205
|
+
useBackgroundSessionSync({
|
|
1206
|
+
enabled: backgroundSession,
|
|
1207
|
+
oxyServices,
|
|
1208
|
+
userId: user?.id ?? null,
|
|
1209
|
+
canUsePrivateApi,
|
|
1210
|
+
});
|
|
1211
|
+
|
|
1198
1212
|
const contextValue: OxyContextState = useMemo(
|
|
1199
1213
|
() => ({
|
|
1200
1214
|
user,
|
|
@@ -176,6 +176,28 @@ export interface OxyContextProviderProps {
|
|
|
176
176
|
* @default 'popup'
|
|
177
177
|
*/
|
|
178
178
|
webAuthMode?: WebAuthMode;
|
|
179
|
+
/**
|
|
180
|
+
* Let NATIVE background code (a home-screen widget's WorkManager worker, a sync
|
|
181
|
+
* job) authenticate while the app process is dead and there is no JS runtime.
|
|
182
|
+
*
|
|
183
|
+
* With this on, the SDK provisions a purpose-built background credential
|
|
184
|
+
* whenever the app runs and stores it where `so.oxy.session.OxyBackgroundSession`
|
|
185
|
+
* can read it; Kotlin then exchanges it for a short access token on demand. The
|
|
186
|
+
* app writes no session code — this prop is the whole integration.
|
|
187
|
+
*
|
|
188
|
+
* OFF by default, because a credential that nobody needs is exposure that
|
|
189
|
+
* nobody needs. Turn it on only in an app that actually has background code to
|
|
190
|
+
* authenticate. Android-only today; inert on web and iOS.
|
|
191
|
+
*
|
|
192
|
+
* The credential cannot create a session (only the running app can provision
|
|
193
|
+
* one), cannot rotate or otherwise disturb the app's own device credential, and
|
|
194
|
+
* is re-authorized server-side on every use so it can never outlive a sign-out.
|
|
195
|
+
* It does NOT reduce authority: the token it mints is a full user access token,
|
|
196
|
+
* exactly like the device credential's.
|
|
197
|
+
*
|
|
198
|
+
* @default false
|
|
199
|
+
*/
|
|
200
|
+
backgroundSession?: boolean;
|
|
179
201
|
onAuthStateChange?: (user: User | null) => void;
|
|
180
202
|
onError?: (error: ApiError) => void;
|
|
181
203
|
}
|
|
@@ -12,7 +12,7 @@ import { Text } from '@oxyhq/bloom/typography';
|
|
|
12
12
|
import { Button } from '@oxyhq/bloom/button';
|
|
13
13
|
import { TextField, TextFieldInput } from '@oxyhq/bloom/text-field';
|
|
14
14
|
import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list';
|
|
15
|
-
import type
|
|
15
|
+
import { getNormalizedUserHandle, type UpdateAccountInput } from '@oxyhq/core';
|
|
16
16
|
import type { BaseScreenProps } from '../types/navigation';
|
|
17
17
|
import { SettingsIcon } from '../components/SettingsIcon';
|
|
18
18
|
import { useOxy } from '../context/OxyContext';
|
|
@@ -67,9 +67,9 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({ onClose, goBack, nav
|
|
|
67
67
|
// Seed the form from the account during render (no useEffect): the first time
|
|
68
68
|
// the query resolves we capture its values into local edit state.
|
|
69
69
|
if (node && !seeded) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
setDisplayName(
|
|
71
|
+
node.account?.name?.displayName ?? getNormalizedUserHandle(node.account) ?? '',
|
|
72
|
+
);
|
|
73
73
|
setBio(node.account?.bio ?? '');
|
|
74
74
|
setSeeded(true);
|
|
75
75
|
}
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
import { surfaces as bloomSurfaces } from '@oxyhq/bloom/surfaces';
|
|
41
41
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
42
42
|
import { toast } from '@oxyhq/bloom';
|
|
43
|
-
import {
|
|
43
|
+
import { getNormalizedUserHandle, logger } from '@oxyhq/core';
|
|
44
44
|
import type { FileMetadata } from '@oxyhq/core';
|
|
45
45
|
import { useOxy } from '../context/OxyContext';
|
|
46
46
|
import { useI18n } from '../hooks/useI18n';
|
|
@@ -133,7 +133,7 @@ async function loadImagePicker(): Promise<ImagePickerModule | null> {
|
|
|
133
133
|
|
|
134
134
|
const ChangeAvatarScreen: React.FC<BaseScreenProps> = ({ navigate, dismiss }) => {
|
|
135
135
|
const bloomTheme = useTheme();
|
|
136
|
-
const { t
|
|
136
|
+
const { t } = useI18n();
|
|
137
137
|
const { user, oxyServices } = useOxy();
|
|
138
138
|
|
|
139
139
|
/** Set when a permission was refused — drives the inline denied notice. */
|
|
@@ -143,7 +143,10 @@ const ChangeAvatarScreen: React.FC<BaseScreenProps> = ({ navigate, dismiss }) =>
|
|
|
143
143
|
|
|
144
144
|
useSurfaceHeader(useMemo(() => ({ title: t('changeAvatar.title') }), [t]));
|
|
145
145
|
|
|
146
|
-
const displayName = useMemo(
|
|
146
|
+
const displayName = useMemo(
|
|
147
|
+
() => user?.name?.displayName ?? getNormalizedUserHandle(user) ?? '',
|
|
148
|
+
[user],
|
|
149
|
+
);
|
|
147
150
|
const avatarUri = useMemo(
|
|
148
151
|
// `thumb` is 256x256 — exactly a 2x source for the 132dp hero.
|
|
149
152
|
() => (user?.avatar ? oxyServices.getFileDownloadUrl(user.avatar, 'thumb') : undefined),
|
|
@@ -3,7 +3,7 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { View } from 'react-native';
|
|
4
4
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
5
5
|
import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list';
|
|
6
|
-
import {
|
|
6
|
+
import { getNormalizedUserHandle } from '@oxyhq/core';
|
|
7
7
|
import type { BaseScreenProps } from '../types/navigation';
|
|
8
8
|
import { Avatar } from '@oxyhq/bloom/avatar';
|
|
9
9
|
import ProfileSummaryCard from '../components/ProfileSummaryCard';
|
|
@@ -24,12 +24,15 @@ import type { ProfileFieldType } from './EditProfileFieldScreen';
|
|
|
24
24
|
*/
|
|
25
25
|
const EditProfileScreen: React.FC<BaseScreenProps> = ({ navigate }) => {
|
|
26
26
|
const bloomTheme = useTheme();
|
|
27
|
-
const { t
|
|
27
|
+
const { t } = useI18n();
|
|
28
28
|
const { user, oxyServices, openAvatarPicker } = useOxy();
|
|
29
29
|
|
|
30
30
|
useSurfaceHeader({ title: t('editProfile.title') || 'Edit Profile' });
|
|
31
31
|
|
|
32
|
-
const displayName = useMemo(
|
|
32
|
+
const displayName = useMemo(
|
|
33
|
+
() => user?.name?.displayName ?? getNormalizedUserHandle(user) ?? '',
|
|
34
|
+
[user],
|
|
35
|
+
);
|
|
33
36
|
const avatarUri = useMemo(
|
|
34
37
|
() => (user?.avatar ? oxyServices.getFileDownloadUrl(user.avatar, 'thumb') : undefined),
|
|
35
38
|
[user?.avatar, oxyServices],
|
|
@@ -283,6 +283,7 @@ const FeedbackScreen: React.FC<BaseScreenProps> = ({
|
|
|
283
283
|
>
|
|
284
284
|
{Array.from({ length: TOTAL_STEPS }, (_, index) => (
|
|
285
285
|
<View
|
|
286
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: fixed step indicators, order never changes
|
|
286
287
|
key={index}
|
|
287
288
|
className={
|
|
288
289
|
currentStep === index
|
|
@@ -15,6 +15,7 @@ import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list'
|
|
|
15
15
|
import {
|
|
16
16
|
getAccountDisplayName,
|
|
17
17
|
getAccountFallbackHandle,
|
|
18
|
+
getNormalizedUserHandle,
|
|
18
19
|
logger as loggerUtil,
|
|
19
20
|
packageInfo,
|
|
20
21
|
} from '@oxyhq/core';
|
|
@@ -120,7 +121,13 @@ const ManageAccountScreen: React.FC<BaseScreenProps> = ({
|
|
|
120
121
|
const [signingOutAllDevices, setSigningOutAllDevices] = useState(false);
|
|
121
122
|
const [signingOut, setSigningOut] = useState(false);
|
|
122
123
|
|
|
123
|
-
const displayName = useMemo(
|
|
124
|
+
const displayName = useMemo(
|
|
125
|
+
() =>
|
|
126
|
+
user?.name?.displayName ??
|
|
127
|
+
getNormalizedUserHandle(user) ??
|
|
128
|
+
getAccountDisplayName(null, locale),
|
|
129
|
+
[user, locale],
|
|
130
|
+
);
|
|
124
131
|
const handle = useMemo(() => getAccountFallbackHandle(user), [user]);
|
|
125
132
|
const avatarUri = useMemo(() => {
|
|
126
133
|
return user?.avatar
|
|
@@ -741,9 +741,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
|
|
|
741
741
|
</View>
|
|
742
742
|
|
|
743
743
|
<BenefitList className="mb-space-24">
|
|
744
|
-
{plan.features.map((feature
|
|
744
|
+
{plan.features.map((feature) => (
|
|
745
745
|
<BenefitRow
|
|
746
|
-
key={
|
|
746
|
+
key={feature}
|
|
747
747
|
icon={<Ionicons name="checkmark" size={18} color={colors.success} />}
|
|
748
748
|
label={feature}
|
|
749
749
|
/>
|
|
@@ -14,7 +14,7 @@ import { useI18n } from '../hooks/useI18n';
|
|
|
14
14
|
import { useSurfaceHeader } from '../hooks/useSurfaceHeader';
|
|
15
15
|
import { useSettingToggles } from '../hooks/useSettingToggle';
|
|
16
16
|
import type { BlockedUser, RestrictedUser } from '@oxyhq/core';
|
|
17
|
-
import {
|
|
17
|
+
import { getNormalizedUserHandle } from '@oxyhq/core';
|
|
18
18
|
import { useOxy } from '../context/OxyContext';
|
|
19
19
|
|
|
20
20
|
interface PrivacySettings {
|
|
@@ -68,7 +68,7 @@ const PrivacySettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
68
68
|
// Privacy settings belong to the ACTIVE account (the org/project/bot when
|
|
69
69
|
// switched, else the personal user).
|
|
70
70
|
const { oxyServices, user } = useOxy();
|
|
71
|
-
const { t
|
|
71
|
+
const { t } = useI18n();
|
|
72
72
|
|
|
73
73
|
useSurfaceHeader({ title: t('privacySettings.title') || 'Privacy Settings' });
|
|
74
74
|
const bloomTheme = useTheme();
|
|
@@ -176,35 +176,37 @@ const PrivacySettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
176
176
|
}, [oxyServices, t]);
|
|
177
177
|
|
|
178
178
|
// Helper to extract user info from blocked/restricted objects.
|
|
179
|
-
// Display names go through the canonical helper so the fallback chain is
|
|
180
|
-
// identical across every UI surface (name → username → publicKey → "Unnamed").
|
|
181
179
|
const extractUserInfo = useCallback((
|
|
182
180
|
item: BlockedUser | RestrictedUser,
|
|
183
181
|
idField: 'blockedId' | 'restrictedId'
|
|
184
182
|
) => {
|
|
185
|
-
let userIdField: string | { _id: string; username?: string; avatar?: string };
|
|
186
|
-
let userShape: { username?: string };
|
|
183
|
+
let userIdField: string | { _id: string; username?: string; avatar?: string; name?: { displayName?: string } };
|
|
184
|
+
let userShape: { username?: string; name?: { displayName?: string } };
|
|
187
185
|
let avatar: string | undefined;
|
|
188
186
|
|
|
189
187
|
if (idField === 'blockedId' && 'blockedId' in item) {
|
|
190
188
|
userIdField = item.blockedId;
|
|
191
189
|
userShape = typeof item.blockedId === 'string'
|
|
192
190
|
? { username: item.username }
|
|
193
|
-
: { username: item.blockedId.username };
|
|
191
|
+
: { username: item.blockedId.username, name: item.blockedId.name };
|
|
194
192
|
avatar = typeof item.blockedId === 'string' ? item.avatar : item.blockedId.avatar;
|
|
195
193
|
} else if (idField === 'restrictedId' && 'restrictedId' in item) {
|
|
196
194
|
userIdField = item.restrictedId;
|
|
197
195
|
userShape = typeof item.restrictedId === 'string'
|
|
198
196
|
? { username: item.username }
|
|
199
|
-
: { username: item.restrictedId.username };
|
|
197
|
+
: { username: item.restrictedId.username, name: item.restrictedId.name };
|
|
200
198
|
avatar = typeof item.restrictedId === 'string' ? item.avatar : item.restrictedId.avatar;
|
|
201
199
|
} else {
|
|
202
|
-
return { userId: '', displayName:
|
|
200
|
+
return { userId: '', displayName: getNormalizedUserHandle(null) ?? '', avatar: undefined };
|
|
203
201
|
}
|
|
204
202
|
|
|
205
203
|
const userId = typeof userIdField === 'string' ? userIdField : userIdField._id;
|
|
206
|
-
return {
|
|
207
|
-
|
|
204
|
+
return {
|
|
205
|
+
userId,
|
|
206
|
+
displayName: userShape.name?.displayName ?? getNormalizedUserHandle(userShape) ?? '',
|
|
207
|
+
avatar,
|
|
208
|
+
};
|
|
209
|
+
}, []);
|
|
208
210
|
|
|
209
211
|
if (isLoading) {
|
|
210
212
|
return (
|
|
@@ -78,7 +78,9 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
|
|
|
78
78
|
);
|
|
79
79
|
throw err;
|
|
80
80
|
}),
|
|
81
|
-
|
|
81
|
+
(isOwnProfile
|
|
82
|
+
? oxyServices.getMyReputationBalance()
|
|
83
|
+
: oxyServices.getReputationBalance(userId))
|
|
82
84
|
.then((balance): { total: number | undefined } => ({ total: balance.total }))
|
|
83
85
|
.catch((): { total: number | undefined } => ({ total: undefined })),
|
|
84
86
|
oxyServices.getUserStats
|
|
@@ -65,7 +65,7 @@ const UserListScreen: React.FC<UserListScreenProps> = ({
|
|
|
65
65
|
const [hasMore, setHasMore] = useState(true);
|
|
66
66
|
|
|
67
67
|
const bloomTheme = useTheme();
|
|
68
|
-
const { t
|
|
68
|
+
const { t } = useI18n();
|
|
69
69
|
|
|
70
70
|
const currentUserId = currentUser ? resolveUserId(currentUser) : '';
|
|
71
71
|
|
|
@@ -199,7 +199,7 @@ const UserListScreen: React.FC<UserListScreenProps> = ({
|
|
|
199
199
|
</TouchableOpacity>
|
|
200
200
|
);
|
|
201
201
|
},
|
|
202
|
-
[handleUserPress, currentUserId, oxyServices
|
|
202
|
+
[handleUserPress, currentUserId, oxyServices]
|
|
203
203
|
);
|
|
204
204
|
|
|
205
205
|
const renderEmpty = useCallback(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import { useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { View, StyleSheet } from 'react-native';
|
|
4
|
-
import type { ReputationTransaction, TrustTier } from '@oxyhq/
|
|
4
|
+
import type { ReputationTransaction, TrustTier } from '@oxyhq/contracts';
|
|
5
5
|
import Ionicons from '@expo/vector-icons/Ionicons';
|
|
6
6
|
import { Chip } from '@oxyhq/bloom/chip';
|
|
7
7
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
@@ -36,7 +36,7 @@ const TrustCenterScreen: React.FC<BaseScreenProps> = ({
|
|
|
36
36
|
setIsLoading(true);
|
|
37
37
|
setError(null);
|
|
38
38
|
Promise.all([
|
|
39
|
-
oxyServices.
|
|
39
|
+
oxyServices.getMyReputationBalance(),
|
|
40
40
|
oxyServices.getReputationTransactions(user.id, 20, 0),
|
|
41
41
|
])
|
|
42
42
|
.then(([balance, txns]) => {
|