implementing account module

This commit is contained in:
balzack 2024-08-27 18:52:56 -07:00
parent 259cdd2680
commit eea9583968
20 changed files with 631 additions and 75 deletions

View File

@ -25,6 +25,7 @@ export class SessionStore implements SqlStore {
stmt: string,
params: (string | number | null)[],
): Promise<any[]> {
console.log('GET: ', stmt);
const res = await this.db.executeSql(stmt, params);
const rows = [];
if (res[0] && res[0].rows && res[0].rows.length > 0) {

View File

@ -1,7 +1,7 @@
import {useState, useEffect, useRef} from 'react';
import {DatabagSDK, Session} from 'databag-client-sdk';
import {SessionStore} from '../SessionStore';
const DATABAG_DB = 'db_v201.db';
const DATABAG_DB = 'db_v202.db';
export function useAppContext() {
const sdk = useRef(new DatabagSDK(null));

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,12 @@
#import "AppDelegate.h"
#import <Firebase.h>
#import <React/RCTBundleURLProvider.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
[FIRApp configure];
{
self.moduleName = @"Databag";
// You can add your custom initial props in the dictionary below.

View File

@ -17,6 +17,9 @@ end
target 'Databag' do
config = use_native_modules!
use_frameworks! :linkage => :static
$RNFirebaseAsStaticFramework = true
use_react_native!(
:path => config[:reactNativePath],
# An absolute path to your application root.

View File

@ -2,11 +2,86 @@ PODS:
- boost (1.83.0)
- DoubleConversion (1.1.6)
- FBLazyVector (0.74.3)
- Firebase/CoreOnly (10.7.0):
- FirebaseCore (= 10.7.0)
- Firebase/Messaging (10.7.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 10.7.0)
- FirebaseCore (10.7.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
- FirebaseCoreExtension (10.7.0):
- FirebaseCore (~> 10.0)
- FirebaseCoreInternal (10.29.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- FirebaseInstallations (10.29.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- PromisesObjC (~> 2.1)
- FirebaseMessaging (10.7.0):
- FirebaseCore (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleDataTransport (~> 9.2)
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Reachability (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- nanopb (< 2.30910.0, >= 2.30908.0)
- fmt (9.1.0)
- glog (0.3.5)
- GoogleDataTransport (9.4.1):
- GoogleUtilities/Environment (~> 7.7)
- nanopb (< 2.30911.0, >= 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/AppDelegateSwizzler (7.13.3):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Privacy
- GoogleUtilities/Environment (7.13.3):
- GoogleUtilities/Privacy
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.13.3):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/Network (7.13.3):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Privacy
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.13.3)":
- GoogleUtilities/Privacy
- GoogleUtilities/Privacy (7.13.3)
- GoogleUtilities/Reachability (7.13.3):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GoogleUtilities/UserDefaults (7.13.3):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- hermes-engine (0.74.3):
- hermes-engine/Pre-built (= 0.74.3)
- hermes-engine/Pre-built (0.74.3)
- JitsiWebRTC (118.0.0)
- libwebp (1.3.2):
- libwebp/demux (= 1.3.2)
- libwebp/mux (= 1.3.2)
- libwebp/sharpyuv (= 1.3.2)
- libwebp/webp (= 1.3.2)
- libwebp/demux (1.3.2):
- libwebp/webp
- libwebp/mux (1.3.2):
- libwebp/demux
- libwebp/sharpyuv (1.3.2)
- libwebp/webp (1.3.2):
- libwebp/sharpyuv
- nanopb (2.30909.1):
- nanopb/decode (= 2.30909.1)
- nanopb/encode (= 2.30909.1)
- nanopb/decode (2.30909.1)
- nanopb/encode (2.30909.1)
- PromisesObjC (2.4.0)
- RCT-Folly (2024.01.01.00):
- boost
- DoubleConversion
@ -956,10 +1031,32 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-create-thumbnail (1.6.4):
- React-Core
- react-native-document-picker (8.2.2):
- React-Core
- react-native-image-resizer (3.0.10):
- React-Core
- react-native-keep-awake (1.2.4):
- React-Core
- react-native-receive-sharing-intent (2.0.0):
- React-Core
- react-native-rsa-native (2.0.5):
- React
- react-native-safe-area-context (4.10.9):
- React-Core
- react-native-sqlite-storage (6.0.1):
- React-Core
- react-native-unifiedpush-connector (0.1.8):
- React-Core
- react-native-video (5.2.1):
- React-Core
- react-native-video/Video (= 5.2.1)
- react-native-video/Video (5.2.1):
- React-Core
- react-native-webrtc (118.0.7):
- JitsiWebRTC (~> 118.0.0)
- React-Core
- React-nativeconfig (0.74.3)
- React-NativeModulesApple (0.74.3):
- glog
@ -1189,6 +1286,123 @@ PODS:
- React-logger (= 0.74.3)
- React-perflogger (= 0.74.3)
- React-utils (= 0.74.3)
- ReactNativeIncallManager (4.2.0):
- React-Core
- rn-fetch-blob (0.12.0):
- React-Core
- RNCClipboard (1.14.1):
- React-Core
- RNDeviceInfo (10.14.0):
- React-Core
- RNFastImage (8.6.3):
- React-Core
- SDWebImage (~> 5.11.1)
- SDWebImageWebPCoder (~> 0.8.4)
- RNFBApp (17.5.0):
- Firebase/CoreOnly (= 10.7.0)
- React-Core
- RNFBMessaging (17.5.0):
- Firebase/Messaging (= 10.7.0)
- FirebaseCoreExtension (= 10.7.0)
- React-Core
- RNFBApp
- RNFS (2.20.0):
- React-Core
- RNGestureHandler (2.18.1):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Codegen
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNImageCropPicker (0.39.0):
- React-Core
- React-RCTImage
- RNImageCropPicker/QBImagePickerController (= 0.39.0)
- TOCropViewController
- RNImageCropPicker/QBImagePickerController (0.39.0):
- React-Core
- React-RCTImage
- TOCropViewController
- RNReanimated (3.15.0):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Codegen
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNReanimated/reanimated (= 3.15.0)
- RNReanimated/worklets (= 3.15.0)
- Yoga
- RNReanimated/reanimated (3.15.0):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Codegen
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNReanimated/worklets (3.15.0):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Codegen
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNScreens (3.34.0):
- DoubleConversion
- glog
@ -1211,28 +1425,18 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNVectorIcons (10.1.0):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Codegen
- RNShare (8.2.2):
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNVectorIcons (9.2.0):
- React-Core
- SDWebImage (5.11.1):
- SDWebImage/Core (= 5.11.1)
- SDWebImage/Core (5.11.1)
- SDWebImageWebPCoder (0.8.5):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.10)
- SocketRocket (0.7.0)
- TOCropViewController (2.7.4)
- Yoga (0.0.0)
DEPENDENCIES:
@ -1269,8 +1473,17 @@ DEPENDENCIES:
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
- "react-native-blur (from `../node_modules/@react-native-community/blur`)"
- react-native-create-thumbnail (from `../node_modules/react-native-create-thumbnail`)
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
- "react-native-image-resizer (from `../node_modules/@bam.tech/react-native-image-resizer`)"
- "react-native-keep-awake (from `../node_modules/@sayem314/react-native-keep-awake`)"
- react-native-receive-sharing-intent (from `../node_modules/react-native-receive-sharing-intent`)
- react-native-rsa-native (from `../node_modules/react-native-rsa-native`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-sqlite-storage (from `../node_modules/react-native-sqlite-storage`)
- react-native-unifiedpush-connector (from `../node_modules/react-native-unifiedpush-connector`)
- react-native-video (from `../node_modules/react-native-video`)
- react-native-webrtc (from `../node_modules/react-native-webrtc`)
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
@ -1294,13 +1507,40 @@ DEPENDENCIES:
- React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- ReactNativeIncallManager (from `../node_modules/react-native-incall-manager`)
- rn-fetch-blob (from `../node_modules/rn-fetch-blob`)
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- RNFastImage (from `../node_modules/react-native-fast-image`)
- "RNFBApp (from `../node_modules/@react-native-firebase/app`)"
- "RNFBMessaging (from `../node_modules/@react-native-firebase/messaging`)"
- RNFS (from `../node_modules/react-native-fs`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
- RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNShare (from `../node_modules/react-native-share`)
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS:
trunk:
- Firebase
- FirebaseCore
- FirebaseCoreExtension
- FirebaseCoreInternal
- FirebaseInstallations
- FirebaseMessaging
- GoogleDataTransport
- GoogleUtilities
- JitsiWebRTC
- libwebp
- nanopb
- PromisesObjC
- SDWebImage
- SDWebImageWebPCoder
- SocketRocket
- TOCropViewController
EXTERNAL SOURCES:
boost:
@ -1366,10 +1606,28 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon"
react-native-blur:
:path: "../node_modules/@react-native-community/blur"
react-native-create-thumbnail:
:path: "../node_modules/react-native-create-thumbnail"
react-native-document-picker:
:path: "../node_modules/react-native-document-picker"
react-native-image-resizer:
:path: "../node_modules/@bam.tech/react-native-image-resizer"
react-native-keep-awake:
:path: "../node_modules/@sayem314/react-native-keep-awake"
react-native-receive-sharing-intent:
:path: "../node_modules/react-native-receive-sharing-intent"
react-native-rsa-native:
:path: "../node_modules/react-native-rsa-native"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-sqlite-storage:
:path: "../node_modules/react-native-sqlite-storage"
react-native-unifiedpush-connector:
:path: "../node_modules/react-native-unifiedpush-connector"
react-native-video:
:path: "../node_modules/react-native-video"
react-native-webrtc:
:path: "../node_modules/react-native-webrtc"
React-nativeconfig:
:path: "../node_modules/react-native/ReactCommon"
React-NativeModulesApple:
@ -1416,8 +1674,32 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/react/utils"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
ReactNativeIncallManager:
:path: "../node_modules/react-native-incall-manager"
rn-fetch-blob:
:path: "../node_modules/rn-fetch-blob"
RNCClipboard:
:path: "../node_modules/@react-native-clipboard/clipboard"
RNDeviceInfo:
:path: "../node_modules/react-native-device-info"
RNFastImage:
:path: "../node_modules/react-native-fast-image"
RNFBApp:
:path: "../node_modules/@react-native-firebase/app"
RNFBMessaging:
:path: "../node_modules/@react-native-firebase/messaging"
RNFS:
:path: "../node_modules/react-native-fs"
RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler"
RNImageCropPicker:
:path: "../node_modules/react-native-image-crop-picker"
RNReanimated:
:path: "../node_modules/react-native-reanimated"
RNScreens:
:path: "../node_modules/react-native-screens"
RNShare:
:path: "../node_modules/react-native-share"
RNVectorIcons:
:path: "../node_modules/react-native-vector-icons"
Yoga:
@ -1427,64 +1709,100 @@ SPEC CHECKSUMS:
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
FBLazyVector: 7e977dd099937dc5458851233141583abba49ff2
Firebase: 0219acf760880eeec8ce479895bd7767466d9f81
FirebaseCore: e317665b9d744727a97e623edbbed009320afdd7
FirebaseCoreExtension: f17247ba8c61e4d3c8d136b5e2de3cb4ac6a85b6
FirebaseCoreInternal: df84dd300b561c27d5571684f389bf60b0a5c934
FirebaseInstallations: 913cf60d0400ebd5d6b63a28b290372ab44590dd
FirebaseMessaging: ac9062bcc35ed56e15a0241d8fd317022499baf8
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
hermes-engine: 1f547997900dd0752dc0cc0ae6dd16173c49e09b
JitsiWebRTC: 3a41671ef65a51d7204323814b055a2690b921c7
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47
RCTDeprecation: 4c7eeb42be0b2e95195563c49be08d0b839d22b4
RCTRequired: d530a0f489699c8500e944fde963102c42dcd0c2
RCTTypeSafety: b20878506b094fa3d9007d7b9e4be0faa3562499
React: 2f9da0177233f60fa3462d83fcccde245759f81a
React-callinvoker: d0205f0dcebf72ec27263ab41e3a5ad827ed503f
React-Codegen: b4457c8557cb61a27508745f8b03f16afeb9ef59
React-Codegen: 27212e14727ad7d6d9fd1b1967fbf21929e4ce29
React-Core: 690ebbbf8f8dcfba6686ce8927731d3f025c3114
React-CoreModules: 185da31f5eb2e6043c3d19b10c64c4661322ed6a
React-cxxreact: c53d2ac9246235351086b8c588feaf775b4ec7f7
React-debug: dd8f7c772fda4196814a3b12620863d1d98b3a53
React-Fabric: 68935648d5c81e6b84445d9e726a79301f1fac8f
React-FabricImage: c92bd5ed4b553c800ca39aee305aaf8dd3e9f4b0
React-featureflags: ead50fe0ee4ab9278b5fd9f3f2f0f63e316452f4
React-graphics: 71c87b09041e45c61809cd357436e570dea5ed48
React-debug: 40caf8ab4c0fd3afe831912e3d4d0e7303eecc5d
React-Fabric: 51ccb4f7e45df5837e796f339d602737063c463e
React-FabricImage: 376b7a81bfe64102e7da5fc85cd1775638584c92
React-featureflags: 0d0576ae8306801a8a660b36afcdbda04dd7cc12
React-graphics: e0e6b8fbb1c5968c70d3584dccec42544b769b60
React-hermes: 917b7ab4c3cb9204c2ad020d74f313830097148b
React-ImageManager: 1086d48d00fcb511ea119bfc58fb12a72c4dcb95
React-jserrorhandler: 84d45913636750c2e620a8c8e049964967040405
React-ImageManager: 5cebcc0136f3b309c7f5189b96e6c0ebd0ec8192
React-jserrorhandler: 5dc7e036cba3b7d167380c02afabf818ad0b2f98
React-jsi: 024b933267079f80c30a5cae97bf5ce521217505
React-jsiexecutor: 45cb079c87db3f514da3acfc686387a0e01de5c5
React-jsinspector: 1066f8b3da937daf8ced4cf3786eb29e1e4f9b30
React-jsitracing: 6b3c8c98313642140530f93c46f5a6ca4530b446
React-jsinspector: c9551971f1298163c93e2bfb082c2b4245618fc6
React-jsitracing: 1aa5681c353b41573b03e0e480a5adf5fa1c56d8
React-logger: fa92ba4d3a5d39ac450f59be2a3cec7b099f0304
React-Mapbuffer: 9f68550e7c6839d01411ac8896aea5c868eff63a
react-native-blur: a2acf22fd7bd13621df5e0b1c130b81adea7009c
React-Mapbuffer: 70da5955150a58732e9336a0c7e71cd49e909f25
react-native-blur: b58f3155f534d975b7647593d93a2e907513addd
react-native-create-thumbnail: e022bcdcba8a0b4529a50d3fa1a832ec921be39d
react-native-document-picker: cd4d6b36a5207ad7a9e599ebb9eb0c2e84fa0b87
react-native-image-resizer: fd0c333eca55147bd55c5e054cac95dcd0da6814
react-native-keep-awake: a15b33cd9b94a2da9b0a1c50ac64ac2391d3e330
react-native-receive-sharing-intent: 62ab28c50e6ae56d32b9e841d7452091312a0bc7
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
react-native-safe-area-context: ab8f4a3d8180913bd78ae75dd599c94cce3d5e9a
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
React-nativeconfig: fa5de9d8f4dbd5917358f8ad3ad1e08762f01dcb
React-NativeModulesApple: 585d1b78e0597de364d259cb56007052d0bda5e5
react-native-unifiedpush-connector: 4d60170e5eb46329f15e5da6c1171d3683480bf4
react-native-video: c26780b224543c62d5e1b2a7244a5cd1b50e8253
react-native-webrtc: 8b024c7bb9a005d2b9efeba4c691172dbd00268d
React-nativeconfig: 84806b820491db30175afbf027e99e8415dc63f0
React-NativeModulesApple: 7b79212f8cf496ab554e0b7b09acbd4aa4690260
React-perflogger: 7bb9ba49435ff66b666e7966ee10082508a203e8
React-RCTActionSheet: a2816ae2b5c8523c2bc18a8f874a724a096e6d97
React-RCTAnimation: e78f52d7422bac13e1213e25e9bcbf99be872e1a
React-RCTAppDelegate: 24f46de486cfa3a9f46e4b0786eaf17d92e1e0c6
React-RCTBlob: 9f9d6599d1b00690704dadc4a4bc33a7e76938be
React-RCTFabric: 609e66bb0371b9082c62ed677ee0614efe711bf2
React-RCTFabric: 416d20a24b117a7ec7d32088fc8f359b5e558fa7
React-RCTImage: 39dd5aee6b92213845e1e7a7c41865801dc33493
React-RCTLinking: 35d742a982f901f9ea416d772763e2da65c2dc7d
React-RCTNetwork: b078576c0c896c71905f841716b9f9f5922111dc
React-RCTSettings: 900aab52b5b1212f247c2944d88f4defbf6146f2
React-RCTText: a3895ab4e5df4a5fd41b6f059eed484a0c7016d1
React-RCTVibration: ab4912e1427d8de00ef89e9e6582094c4c25dc05
React-rendererdebug: 542934058708a643fa5743902eb2fedc0833770a
React-rncore: f6c23d9810c8de9e369781bb7b1d5511e9d9f4e7
React-RuntimeApple: ce41ba7df744c7a6c2cc490a9b2e15fc58019508
React-RuntimeCore: 350218ac9ee1412ddc9806f248141c8fb9bccd8b
React-rendererdebug: 8ea55aebb8cba804db2a8449a2f0c80ccfe0ce5a
React-rncore: 1f725aee4e00c317e51cb4d37aca7f6a47da9a11
React-RuntimeApple: c1833d8e82f7c5314c001d61d289849c75217944
React-RuntimeCore: 0a5b37b50737af3505b5801376ae5788532c013e
React-runtimeexecutor: 69cab8ddf409de6d6a855a71c8af9e7290c4e55b
React-RuntimeHermes: 9d0812e3370111dd175aa1fa8bd4da93a9efc4fd
React-runtimescheduler: 0c80752bceb80924cb8a4babc2a8e3ed70d41e87
React-utils: a06061b3887c702235d2dac92dacbd93e1ea079e
ReactCommon: f00e436b3925a7ae44dfa294b43ef360fbd8ccc4
RNScreens: aa943ad421c3ced3ef5a47ede02b0cbfc43a012e
RNVectorIcons: 2a2f79274248390b80684ea3c4400bd374a15c90
React-RuntimeHermes: 44847ba3e8a9394b9829d9a9abde7590624f32d0
React-runtimescheduler: e4ad653e1d2f5ff40ba047446cacde009694f0ed
React-utils: 6f7ac39d9a0de447d4334bb25d144a28c0c5d8c9
ReactCommon: 4a09c7d8a06e93c1e2e988a3b9f3db3d2449f2fc
ReactNativeIncallManager: bfc9c67358cd524882a7c4116dcb311ac2293d4b
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
RNCClipboard: 0a720adef5ec193aa0e3de24c3977222c7e52a37
RNDeviceInfo: 59344c19152c4b2b32283005f9737c5c64b42fba
RNFastImage: 5c9c9fed9c076e521b3f509fe79e790418a544e8
RNFBApp: d59efa0872fff4e27de03cca3c528c203a436ae5
RNFBMessaging: 216693dd5ba4f18ba65fb39fc73a44a23c26190f
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
RNGestureHandler: fc0d83b45872ee937ecc9814012d9b48586b4d7a
RNImageCropPicker: 14fe1c29298fb4018f3186f455c475ab107da332
RNReanimated: 45f0fd1250364dffec9aabd4a0959f2956a5e78b
RNScreens: db442e7b8c7bc8befec2ce057927305ff8598cc8
RNShare: d82e10f6b7677f4b0048c23709bd04098d5aee6c
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Yoga: 88480008ccacea6301ff7bf58726e27a72931c8d
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
Yoga: bd92064a0d558be92786820514d74fc4dddd1233
PODFILE CHECKSUM: 8461018d8deceb200962c829584af7c2eb345c80
PODFILE CHECKSUM: 98a8566a28ef3705c6f2fdf1c3525e90e7ebfdfd
COCOAPODS: 1.15.2

View File

@ -15,8 +15,8 @@
"@braintree/sanitize-url": "^6.0.2",
"@react-native-clipboard/clipboard": "^1.11.1",
"@react-native-community/blur": "^4.3.2",
"@react-native-firebase/app": "^17.2.0",
"@react-native-firebase/messaging": "^17.2.0",
"@react-native-firebase/app": "^17.5.0",
"@react-native-firebase/messaging": "^17.5.0",
"@react-navigation/bottom-tabs": "^6.5.5",
"@react-navigation/drawer": "^6.6.0",
"@react-navigation/native": "^6.1.4",

View File

@ -2387,7 +2387,7 @@ __metadata:
languageName: node
linkType: hard
"@react-native-firebase/app@npm:^17.2.0":
"@react-native-firebase/app@npm:^17.5.0":
version: 17.5.0
resolution: "@react-native-firebase/app@npm:17.5.0"
dependencies:
@ -2404,7 +2404,7 @@ __metadata:
languageName: node
linkType: hard
"@react-native-firebase/messaging@npm:^17.2.0":
"@react-native-firebase/messaging@npm:^17.5.0":
version: 17.5.0
resolution: "@react-native-firebase/messaging@npm:17.5.0"
peerDependencies:
@ -3241,8 +3241,8 @@ __metadata:
"@braintree/sanitize-url": ^6.0.2
"@react-native-clipboard/clipboard": ^1.11.1
"@react-native-community/blur": ^4.3.2
"@react-native-firebase/app": ^17.2.0
"@react-native-firebase/messaging": ^17.2.0
"@react-native-firebase/app": ^17.5.0
"@react-native-firebase/messaging": ^17.5.0
"@react-native/babel-preset": 0.74.85
"@react-native/eslint-config": 0.74.85
"@react-native/metro-config": 0.74.85

View File

@ -4,6 +4,15 @@ import type { AccountStatus } from './types';
import { Store } from './store';
import { defaultAccountEntity, AccountEntity } from './entities';
import { getAccountStatus } from './net/getAccountStatus';
import { addAccountMFAuth } from './net/addAccountMFAuth';
import { setAccountMFAuth } from './net/setAccountMFAuth';
import { removeAccountMFAuth } from './net/removeAccountMFAuth';
import { setAccountLogin } from './net/setAccountLogin';
import { setAccountNotifications } from './net/setAccountNotifications';
import { setAccountSearchable } from './net/setAccountSearchable';
import { setAccountSeal } from './net/setAccountSeal';
import { clearAccountSeal } from './net/clearAccountSeal';
import { Crypto } from './crypto';
const CLOSE_POLL_MS = 100;
const RETRY_POLL_MS = 2000;
@ -16,18 +25,21 @@ export class AccountModule implements Account {
private node: string;
private secure: boolean;
private log: Logging;
private crypto: Crypto | null;
private syncing: boolean;
private closing: boolean;
private revision: number;
private nextRevision: number | null;
private entity: AccountEntity;
private sealKey: { privateKey: string, publicKey: string } | null;
constructor(log: Logging, store: Store, guid: string, token: string, node: string, secure: boolean) {
constructor(log: Logging, store: Store, crypto: Crypto | null, guid: string, token: string, node: string, secure: boolean) {
this.log = log;
this.emitter = new EventEmitter();
this.guid = guid;
this.token = token;
this.node = node;
this.seal = null;
this.secure = secure;
this.revision = 0;
this.entity = defaultAccountEntity;
@ -40,6 +52,7 @@ export class AccountModule implements Account {
private async init() {
this.revision = await this.store.getAccountRevision(this.guid);
this.entity = await this.store.getAccountData(this.guid);
this.seal = await this.store.getSeal(this.guid);
this.syncing = false;
await this.sync();
}
@ -72,12 +85,14 @@ export class AccountModule implements Account {
}
}
}
this.syncing = false;
}
}
public getStatus() {
const { storageUsed, storageAvailable, forwardingAddress, searchable, allowUnseaed, pushEnabled, sealable, seal, enableIce, multiFactorAuth, webPushKey } = this.entity;
return { storageUsed, storageAvailable, forwardingAddress, searchable, allowUnsealed, pushEnabled, sealable, sealSet: Boolean(seal), enableIce, multiFactorAuth, webPushKey };
const sealSet = this.seal && seal && this.seal.publicKey == seal.publicKey && this.seal.privateKey
return { storageUsed, storageAvailable, forwardingAddress, searchable, allowUnsealed, pushEnabled, sealable, sealSet, enableIce, multiFactorAuth, webPushKey };
}
public addStatusListener(ev: (status: AccountStatus) => void): void {
@ -102,37 +117,91 @@ export class AccountModule implements Account {
}
public async enableNotifications(): Promise<void> {
const { node, secure, token } = this;
await setAccountNotifications(node, secure, token, true);
}
public async disableNotifications(): Promise<void> {
const { node, secure, token } = this;
await setAccountNotifications(node, secure, token, false);
}
public async enableRegistry(): Promise<void> {
const { node, secure, token } = this;
await setAccountSearchable(node, secure, token, true);
}
public async disableRegistry(): Promise<void> {
const { node, secure, token } = this;
await setAccountSearchable(node, secure, token, false);
}
public async enableMFA(): Promise<{ secretImage: string, secretText: string }> {
return { secretImage: '', secretText: '' };
const { node, secure, token } = this;
const { image, text } = await addAccountMFAuth(node, secure, token);
return { secretImage: image, secretText: text };
}
public async disableMFA(): Promise<void> {
const { node, secure, token } = this;
await removeAccountMFAuth(node, secure, token);
}
public async confirmMFA(code: string): Promise<void> {
const { node, secure, token } = this;
await setAccountMFAuth(node, secure, token, code);
}
public async setAccountSeal(password: string): Promise<void> {
const { crypto, guid, node, secure, token } = this;
if (!crypto) {
throw new Error('crypto not enabled');
}
const { saltHex } = crypto.pbkdfSalt();
const { aesKeyHex } = crypto.pbkdfKey(saltHex, password);
const { publicKeyB64, privateKeyB64 } = crypto.rsaKey();
const { ivHex } = crypto.aesIv();
const { encryptedDataB64 } = crypto.aesEncrypt(privateKeyB64, ivHex, aesKeyHex);
const entity = { passwordSalt: saltHex, privateKeyIv: ivHex, privateKeyEncrypted: encryptedDataB64, publicKey: publicKeyB64 };
await setAccountSeal(node, secure, token, entity);
const seal = { publicKey: publicKeyB64, privateKey: privateKeyB64 };
this.store.setSeal(guid, seal);
this.seal = seal;
this.emitter.emit('status', this.getStatus());
}
public async clearAccountSeal(): Promise<void> {
const { guid, node, secure, token } = this;
await this.store.clearAccountSeal(guid, node, secure, token);
this.seal = null;
this.emitter.emit('status', this.getStatus());
}
public async unlockAccountSeal(password: string): Promise<void> {
const { guid, entity, crypto } = this;
const { passwordSalt, privateKeyIv, privateKeyEncrypted, publicKey } = entity.seal;
if (!passwordSalt || !privateKeyIv || !privateKeyEncrypted || !publicKey) {
throw new Error('account seal not set');
}
if (!crypto) {
throw new Error('crypto not set');
}
const { aesKeyHex } = crypto.pbkdfKey(passwordSalt, password);
const { data } = crypto.aesDecrypt(privateKeyEncrypted, privateKeyIv, aesKeyHex);
const seal = { publicKey: publicKey, privateKey: data };
this.store.setSeal(guid, seal);
this.seal = seal;
this.emitter.emit('status', this.getStatus());
}
public async setLogin(username: string, password: string): Promise<void> {
const { node, secure, token } = this;
await setAccountLogin(node, secure, token, username, password);
}
}

View File

@ -1,7 +1,7 @@
export interface Crypto {
// generate salt for pbk function
pkdkfSalt(): { saltHex: string };
pbkdfSalt(): { saltHex: string };
// generate aes key with pbkdf2
pbkdfKey(saltHex: string, password: string): { aesKeyHex: string };

View File

@ -0,0 +1,10 @@
import axios from 'redaxios';
export async function addAccountMFAuth(node: string, secure: boolean, token: string): { text: string, image: string } {
const endpoint = `http${secure ? 's' : ''}://${node}/account/mfauth=${token}`;
const response = await axios.post(endpoint);
if (response.status >= 400 && response.status < 600) {
throw new Error('setAccountMFAuth failed');
}
}

View File

@ -0,0 +1,10 @@
import axios from 'redaxios';
export async function setAccountSeal(node: string, secure: boolean, token: string) {
const endpoint = `http${secure ? 's' : ''}://${node}/account/seal?agent=${token}`;
const response = await axios.delete(endpoint);
if (response.status >= 400 && response.status < 600) {
throw new Error('setAccountSeal failed');
}
}

View File

@ -0,0 +1,10 @@
import axios from 'redaxios';
export async function removeAccountMFAuth(node: string, secure: boolean, token: string) {
const endpoint = `http${secure ? 's' : ''}://${node}/account/mfauth=${token}`;
const response = await axios.delete(endpoint);
if (response.status >= 400 && response.status < 600) {
throw new Error('setAccountMFAuth failed');
}
}

View File

@ -0,0 +1,9 @@
import axios from 'redaxios';
import { encode } from './base64';
export async function setAccountLogin(node: string, secure: boolean, token: string, username: string, password: string) {
const endpoint = `http${secure ? 's' : ''}://${node}/account/login?agent=${token}`;
const auth = encode(`${username}:${password}`);
const response = await axios.put(endpoint, null, { auth: `Basic ${auth}` });
return response.data;
}

View File

@ -0,0 +1,10 @@
import axios from 'redaxios';
export async function setAccountMFAuth(node: string, secure: boolean, token: string, code: string) {
const endpoint = `http${secure ? 's' : ''}://${node}/account/mfauth=${token}`;
const response = await axios.put(endpoint, code);
if (response.status >= 400 && response.status < 600) {
throw new Error('setAccountMFAuth failed');
}
}

View File

@ -0,0 +1,10 @@
import axios from 'redaxios';
export async function setAccountNotifications(node: string, secure: boolean, token: string, flag: boolean) {
const endpoint = `http${secure ? 's' : ''}://${node}/account/notification?agent=${token}`;
const response = await axios.put(endpoint, flag);
if (response.status >= 400 && response.status < 600) {
throw new Error('setAccountNotification failed');
}
}

View File

@ -0,0 +1,11 @@
import axios from 'redaxios';
import { SealEntity } from '../entities';
export async function setAccountSeal(node: string, secure: boolean, token: string, seal: SealEntity) {
const endpoint = `http${secure ? 's' : ''}://${node}/account/seal?agent=${token}`;
const response = await axios.put(endpoint, seal);
if (response.status >= 400 && response.status < 600) {
throw new Error('setAccountSeal failed');
}
}

View File

@ -0,0 +1,10 @@
import axios from 'redaxios';
export async function setAccountSearchable(node: string, secure: boolean, token: string, flag: boolean) {
const endpoint = `http${secure ? 's' : ''}://${node}/account/searchable?agent=${token}`;
const response = await axios.put(endpoint, flag);
if (response.status >= 400 && response.status < 600) {
throw new Error('setAccountSearchable failed');
}
}

View File

@ -59,7 +59,7 @@ export class SessionModule implements Session {
this.emitter = new EventEmitter();
this.identity = new IdentityModule(log, this.store, guid, token, node, secure);
this.account = new AccountModule(log, this.store, guid, token, node, secure);
this.account = new AccountModule(log, this.store, this.crypto, guid, token, node, secure);
this.contact = new ContactModule(log, this.store, guid, token, node, secure);
this.alias = new AliasModule(log, this.account, this.store, guid, token, node, secure);
this.attribute = new AttributeModule(log, this.account, this.store, guid, token, node, secure);

View File

@ -6,6 +6,9 @@ export interface Store {
init(): Promise<Login | null>;
setLogin(login: Login): Promise<void>;
clearLogin(): Promise<void>;
getSeal(guid: string): Promise<{ publicKey: string, privateKey: string } | null>;
setSeal(guid: string, seal: { publicKey: string, privateKey: string }): Promise<void>;
clearSeal(guid: string): Promise<void>;
getProfileRevision(guid: string): Promise<number>;
setProfileRevision(guid: string, revision: number): Promise<void>;
@ -41,8 +44,8 @@ export class OfflineStore implements Store {
return unset;
}
private async setAppValue(guid: string, id: string, value: string): Promise<void> {
await this.sql.set('INSERT OR REPLACE INTO app (key, value) values (?, ?)', [`${guid}::${id}`, value]);
private async setAppValue(guid: string, id: string, value: any): Promise<void> {
await this.sql.set('INSERT OR REPLACE INTO app (key, value) values (?, ?)', [`${guid}::${id}`, JSON.stringify(value)]);
}
private async clearAppValue(guid: string, id: string): Promise<void> {
@ -64,13 +67,25 @@ export class OfflineStore implements Store {
public async setLogin(login: Login): Promise<void> {
await this.initLogin(login.guid);
await this.setAppValue('', 'login', JSON.stringify(login));
await this.setAppValue('', 'login', login);
}
public async clearLogin(): Promise<void> {
await this.clearAppValue('', 'login');
}
public async getSeal(guid: string): Promise<{ publicKey: string, privateKey: string } | null> {
return await this.getAppValue(guid, 'seal', null) as { publicKey: string, privateKey: string } | null;
}
public async setSeal(guid: string, seal: { publicKey: string, privateKey: string }): Promise<void> {
await this.setAppValue(guid, 'seal', seal);
}
public async clearSeal(guid: string): Promise<void> {
await this.clearAppValue(guid, 'seal');
}
public async getProfileRevision(guid: string): Promise<number> {
return await this.getAppValue(guid, 'profile_revision', 0) as number;
}
@ -115,24 +130,44 @@ export class OnlineStore implements Store {
this.log = log;
}
private async getAppValue(id: string, unset: any): Promise<any> {
const value = await this.web.getValue(id);
private async getAppValue(guid: string, id: string, unset: any): Promise<any> {
const value = await this.web.getValue(`${guid}::${id}`);
if (value != null) {
return JSON.parse(value);
}
return unset;
}
private async setAppValue(guid: string, id: string, value: any): Promise<void> {
await this.web.setValue(`${guid}::${id}`, JSON.stringify(value));
}
private async clearAppValue(guid: string, id: string): Promise<void> {
await this.web.clearValue(`${guid}::${id}`);
}
public async init(): Promise<Login | null> {
return this.getAppValue('login', null);
return await this.getAppValue('', 'login', null) as Login | null;
}
public async setLogin(login: Login): Promise<void> {
return await this.web.setValue('login', JSON.stringify(login));
await this.setAppValue('', 'login', login);
}
public async clearLogin(): Promise<void> {
return await this.web.clearValue('login');
await this.clearAppValue('', 'login');
}
public async getSeal(guid: string): Promise<{ publicKey: string, privateKey: string } | null> {
return await this.getAppValue(guid, 'seal', null) as { publicKey: string, privateKey: string } | null;
}
public async setSeal(guid: string, seal: { publicKey: string, privateKey: string }): Promise<void> {
await this.setAppValue(guid, 'seal', seal);
}
public async clearSeal(guid: string): Promise<void> {
await this.clearAppValue(guid, 'seal');
}
public async getProfileRevision(guid: string): Promise<number> {
@ -179,6 +214,16 @@ export class NoStore implements Store {
public async clearLogin(): Promise<void> {
}
public async getSeal(guid: string): Promise<{ publicKey: string, privateKey: string } | null> {
return null;
}
public async setSeal(guid: string, seal: { publicKey: string, privateKey: string }): Promise<void> {
}
public async clearSeal(guid: string): Promise<void> {
}
public async getProfileRevision(guid: string): Promise<number> {
return 0;
}