diff --git a/native/account/registration/username-selection.react.js b/native/account/registration/username-selection.react.js
index b9174db82..52c233a3c 100644
--- a/native/account/registration/username-selection.react.js
+++ b/native/account/registration/username-selection.react.js
@@ -1,227 +1,239 @@
// @flow
import invariant from 'invariant';
import * as React from 'react';
import { View, Text } from 'react-native';
import {
exactSearchUser,
exactSearchUserActionTypes,
} from 'lib/actions/user-actions.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { validUsernameRegex } from 'lib/shared/account-utils.js';
import { useLegacyAshoatKeyserverCall } from 'lib/utils/action-utils.js';
import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
+import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js';
import { isValidEthereumAddress } from 'lib/utils/siwe-utils.js';
import RegistrationButtonContainer from './registration-button-container.react.js';
import RegistrationButton from './registration-button.react.js';
import RegistrationContainer from './registration-container.react.js';
import RegistrationContentContainer from './registration-content-container.react.js';
import { RegistrationContext } from './registration-context.js';
import type { RegistrationNavigationProp } from './registration-navigator.react.js';
import RegistrationTextInput from './registration-text-input.react.js';
import type { CoolOrNerdMode } from './registration-types.js';
+import { commRustModule } from '../../native-modules.js';
import {
type NavigationRoute,
PasswordSelectionRouteName,
} from '../../navigation/route-names.js';
import { useSelector } from '../../redux/redux-utils.js';
import { useStyles } from '../../themes/colors.js';
const exactSearchUserLoadingStatusSelector = createLoadingStatusSelector(
exactSearchUserActionTypes,
);
export type UsernameSelectionParams = {
+userSelections: {
+coolOrNerdMode: CoolOrNerdMode,
+keyserverURL: string,
},
};
type UsernameError = 'username_invalid' | 'username_taken';
type Props = {
+navigation: RegistrationNavigationProp<'UsernameSelection'>,
+route: NavigationRoute<'UsernameSelection'>,
};
function UsernameSelection(props: Props): React.Node {
const registrationContext = React.useContext(RegistrationContext);
invariant(registrationContext, 'registrationContext should be set');
const { cachedSelections, setCachedSelections } = registrationContext;
const [username, setUsername] = React.useState(
cachedSelections.username ?? '',
);
const validUsername =
username.search(validUsernameRegex) > -1 &&
!isValidEthereumAddress(username.toLowerCase());
const [usernameError, setUsernameError] = React.useState();
const checkUsernameValidity = React.useCallback(() => {
if (!validUsername) {
setUsernameError('username_invalid');
return false;
}
setUsernameError(null);
return true;
}, [validUsername]);
const { userSelections } = props.route.params;
const { keyserverURL } = userSelections;
const serverCallParamOverride = React.useMemo(
() => ({
urlPrefix: keyserverURL,
}),
[keyserverURL],
);
const exactSearchUserCall = useLegacyAshoatKeyserverCall(
exactSearchUser,
serverCallParamOverride,
);
const dispatchActionPromise = useDispatchActionPromise();
const { navigate } = props.navigation;
const onProceed = React.useCallback(async () => {
if (!checkUsernameValidity()) {
return;
}
- const searchPromise = exactSearchUserCall(username);
- void dispatchActionPromise(exactSearchUserActionTypes, searchPromise);
- const { userInfo } = await searchPromise;
+ let userAlreadyExists;
+ if (usingCommServicesAccessToken) {
+ const findUserIDResponseString =
+ await commRustModule.findUserIDForUsername(username);
+ const findUserIDResponse = JSON.parse(findUserIDResponseString);
+ userAlreadyExists =
+ !!findUserIDResponse.userID || findUserIDResponse.isReserved;
+ } else {
+ const searchPromise = exactSearchUserCall(username);
+ void dispatchActionPromise(exactSearchUserActionTypes, searchPromise);
+ const { userInfo } = await searchPromise;
+ userAlreadyExists = !!userInfo;
+ }
- if (userInfo) {
+ if (userAlreadyExists) {
setUsernameError('username_taken');
return;
}
setUsernameError(undefined);
setCachedSelections(oldUserSelections => ({
...oldUserSelections,
username,
}));
navigate<'PasswordSelection'>({
name: PasswordSelectionRouteName,
params: {
userSelections: {
...userSelections,
username,
},
},
});
}, [
checkUsernameValidity,
username,
exactSearchUserCall,
dispatchActionPromise,
setCachedSelections,
navigate,
userSelections,
]);
const exactSearchUserCallLoading = useSelector(
state => exactSearchUserLoadingStatusSelector(state) === 'loading',
);
let buttonVariant = 'disabled';
if (exactSearchUserCallLoading) {
buttonVariant = 'loading';
} else if (validUsername) {
buttonVariant = 'enabled';
}
const styles = useStyles(unboundStyles);
let errorText;
if (usernameError === 'username_invalid') {
errorText = (
<>
Usernames must:
{'1. '}
Be at least one character long.
{'2. '}
Start with either a letter or a number.
{'3. '}
Contain only letters, numbers, or the characters “-” and “_”.
>
);
} else if (usernameError === 'username_taken') {
errorText = (
Username taken. Please try another one
);
}
const shouldAutoFocus = React.useRef(!cachedSelections.username);
return (
Pick a username
{errorText}
);
}
const unboundStyles = {
header: {
fontSize: 24,
color: 'panelForegroundLabel',
paddingBottom: 16,
},
error: {
marginTop: 16,
},
errorText: {
fontFamily: 'Arial',
fontSize: 15,
lineHeight: 20,
color: 'redText',
},
listItem: {
flexDirection: 'row',
},
listItemNumber: {
fontWeight: 'bold',
},
listItemContent: {
flexShrink: 1,
},
};
export default UsernameSelection;
diff --git a/native/cpp/CommonCpp/NativeModules/CommRustModule.cpp b/native/cpp/CommonCpp/NativeModules/CommRustModule.cpp
index 6087261ff..1859c6e37 100644
--- a/native/cpp/CommonCpp/NativeModules/CommRustModule.cpp
+++ b/native/cpp/CommonCpp/NativeModules/CommRustModule.cpp
@@ -1,603 +1,623 @@
#include "CommRustModule.h"
#include "InternalModules/RustPromiseManager.h"
#include "JSIRust.h"
#include "lib.rs.h"
#include
namespace comm {
using namespace facebook::react;
CommRustModule::CommRustModule(std::shared_ptr jsInvoker)
: CommRustModuleSchemaCxxSpecJSI(jsInvoker) {
}
jsi::Value CommRustModule::generateNonce(jsi::Runtime &rt) {
return createPromiseAsJSIValue(
rt, [this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityGenerateNonce(currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::registerPasswordUser(
jsi::Runtime &rt,
jsi::String username,
jsi::String password,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) {
auto usernameRust = jsiStringToRustString(username, rt);
auto passwordRust = jsiStringToRustString(password, rt);
auto keyPayloadRust = jsiStringToRustString(keyPayload, rt);
auto keyPayloadSignatureRust = jsiStringToRustString(keyPayloadSignature, rt);
auto contentPrekeyRust = jsiStringToRustString(contentPrekey, rt);
auto contentPrekeySignatureRust =
jsiStringToRustString(contentPrekeySignature, rt);
auto notifPrekeyRust = jsiStringToRustString(notifPrekey, rt);
auto notifPrekeySignatureRust =
jsiStringToRustString(notifPrekeySignature, rt);
auto contentOneTimeKeysRust = jsiStringArrayToRustVec(contentOneTimeKeys, rt);
auto notifOneTimeKeysRust = jsiStringArrayToRustVec(notifOneTimeKeys, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityRegisterPasswordUser(
usernameRust,
passwordRust,
keyPayloadRust,
keyPayloadSignatureRust,
contentPrekeyRust,
contentPrekeySignatureRust,
notifPrekeyRust,
notifPrekeySignatureRust,
contentOneTimeKeysRust,
notifOneTimeKeysRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::logInPasswordUser(
jsi::Runtime &rt,
jsi::String username,
jsi::String password,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) {
auto usernameRust = jsiStringToRustString(username, rt);
auto passwordRust = jsiStringToRustString(password, rt);
auto keyPayloadRust = jsiStringToRustString(keyPayload, rt);
auto keyPayloadSignatureRust = jsiStringToRustString(keyPayloadSignature, rt);
auto contentPrekeyRust = jsiStringToRustString(contentPrekey, rt);
auto contentPrekeySignatureRust =
jsiStringToRustString(contentPrekeySignature, rt);
auto notifPrekeyRust = jsiStringToRustString(notifPrekey, rt);
auto notifPrekeySignatureRust =
jsiStringToRustString(notifPrekeySignature, rt);
auto contentOneTimeKeysRust = jsiStringArrayToRustVec(contentOneTimeKeys, rt);
auto notifOneTimeKeysRust = jsiStringArrayToRustVec(notifOneTimeKeys, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityLogInPasswordUser(
usernameRust,
passwordRust,
keyPayloadRust,
keyPayloadSignatureRust,
contentPrekeyRust,
contentPrekeySignatureRust,
notifPrekeyRust,
notifPrekeySignatureRust,
contentOneTimeKeysRust,
notifOneTimeKeysRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::registerWalletUser(
jsi::Runtime &rt,
jsi::String siweMessage,
jsi::String siweSignature,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) {
auto siweMessageRust = jsiStringToRustString(siweMessage, rt);
auto siweSignatureRust = jsiStringToRustString(siweSignature, rt);
auto keyPayloadRust = jsiStringToRustString(keyPayload, rt);
auto keyPayloadSignatureRust = jsiStringToRustString(keyPayloadSignature, rt);
auto contentPrekeyRust = jsiStringToRustString(contentPrekey, rt);
auto contentPrekeySignatureRust =
jsiStringToRustString(contentPrekeySignature, rt);
auto notifPrekeyRust = jsiStringToRustString(notifPrekey, rt);
auto notifPrekeySignatureRust =
jsiStringToRustString(notifPrekeySignature, rt);
auto contentOneTimeKeysRust = jsiStringArrayToRustVec(contentOneTimeKeys, rt);
auto notifOneTimeKeysRust = jsiStringArrayToRustVec(notifOneTimeKeys, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityRegisterWalletUser(
siweMessageRust,
siweSignatureRust,
keyPayloadRust,
keyPayloadSignatureRust,
contentPrekeyRust,
contentPrekeySignatureRust,
notifPrekeyRust,
notifPrekeySignatureRust,
contentOneTimeKeysRust,
notifOneTimeKeysRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::logInWalletUser(
jsi::Runtime &rt,
jsi::String siweMessage,
jsi::String siweSignature,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) {
auto siweMessageRust = jsiStringToRustString(siweMessage, rt);
auto siweSignatureRust = jsiStringToRustString(siweSignature, rt);
auto keyPayloadRust = jsiStringToRustString(keyPayload, rt);
auto keyPayloadSignatureRust = jsiStringToRustString(keyPayloadSignature, rt);
auto contentPrekeyRust = jsiStringToRustString(contentPrekey, rt);
auto contentPrekeySignatureRust =
jsiStringToRustString(contentPrekeySignature, rt);
auto notifPrekeyRust = jsiStringToRustString(notifPrekey, rt);
auto notifPrekeySignatureRust =
jsiStringToRustString(notifPrekeySignature, rt);
auto contentOneTimeKeysRust = jsiStringArrayToRustVec(contentOneTimeKeys, rt);
auto notifOneTimeKeysRust = jsiStringArrayToRustVec(notifOneTimeKeys, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityLogInWalletUser(
siweMessageRust,
siweSignatureRust,
keyPayloadRust,
keyPayloadSignatureRust,
contentPrekeyRust,
contentPrekeySignatureRust,
notifPrekeyRust,
notifPrekeySignatureRust,
contentOneTimeKeysRust,
notifOneTimeKeysRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::updatePassword(
jsi::Runtime &rt,
jsi::String userID,
jsi::String deviceID,
jsi::String accessToken,
jsi::String password) {
auto userIDRust = jsiStringToRustString(userID, rt);
auto deviceIDRust = jsiStringToRustString(deviceID, rt);
auto accessTokenRust = jsiStringToRustString(accessToken, rt);
auto passwordRust = jsiStringToRustString(password, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityUpdateUserPassword(
userIDRust,
deviceIDRust,
accessTokenRust,
passwordRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::deleteUser(
jsi::Runtime &rt,
jsi::String userID,
jsi::String deviceID,
jsi::String accessToken) {
auto userIDRust = jsiStringToRustString(userID, rt);
auto deviceIDRust = jsiStringToRustString(deviceID, rt);
auto accessTokenRust = jsiStringToRustString(accessToken, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityDeleteUser(
userIDRust, deviceIDRust, accessTokenRust, currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::getOutboundKeysForUser(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String userID) {
auto authUserIDRust = jsiStringToRustString(authUserID, rt);
auto authDeviceIDRust = jsiStringToRustString(authDeviceID, rt);
auto authAccessTokenRust = jsiStringToRustString(authAccessToken, rt);
auto userIDRust = jsiStringToRustString(userID, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityGetOutboundKeysForUser(
authUserIDRust,
authDeviceIDRust,
authAccessTokenRust,
userIDRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::getInboundKeysForUser(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String userID) {
auto authUserIDRust = jsiStringToRustString(authUserID, rt);
auto authDeviceIDRust = jsiStringToRustString(authDeviceID, rt);
auto authAccessTokenRust = jsiStringToRustString(authAccessToken, rt);
auto userIDRust = jsiStringToRustString(userID, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityGetInboundKeysForUser(
authUserIDRust,
authDeviceIDRust,
authAccessTokenRust,
userIDRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::versionSupported(jsi::Runtime &rt) {
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityVersionSupported(currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::uploadOneTimeKeys(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::Array contentOneTimePreKeys,
jsi::Array notifOneTimePreKeys) {
auto authUserIDRust = jsiStringToRustString(authUserID, rt);
auto authDeviceIDRust = jsiStringToRustString(authDeviceID, rt);
auto authAccessTokenRust = jsiStringToRustString(authAccessToken, rt);
auto contentOneTimePreKeysRust =
jsiStringArrayToRustVec(contentOneTimePreKeys, rt);
auto notifOneTimePreKeysRust =
jsiStringArrayToRustVec(notifOneTimePreKeys, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityUploadOneTimeKeys(
authUserIDRust,
authDeviceIDRust,
authAccessTokenRust,
contentOneTimePreKeysRust,
notifOneTimePreKeysRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::getKeyserverKeys(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String keyserverID) {
auto authUserIDRust = jsiStringToRustString(authUserID, rt);
auto authDeviceIDRust = jsiStringToRustString(authDeviceID, rt);
auto authAccessTokenRust = jsiStringToRustString(authAccessToken, rt);
auto keyserverIDRust = jsiStringToRustString(keyserverID, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityGetKeyserverKeys(
authUserIDRust,
authDeviceIDRust,
authAccessTokenRust,
keyserverIDRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::getDeviceListForUser(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String userID,
std::optional sinceTimestamp) {
auto authUserIDRust = jsiStringToRustString(authUserID, rt);
auto authDeviceIDRust = jsiStringToRustString(authDeviceID, rt);
auto authAccessTokenRust = jsiStringToRustString(authAccessToken, rt);
auto userIDRust = jsiStringToRustString(userID, rt);
auto timestampI64 = static_cast(sinceTimestamp.value_or(0));
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityGetDeviceListForUser(
authUserIDRust,
authDeviceIDRust,
authAccessTokenRust,
userIDRust,
timestampI64,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::updateDeviceList(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String updatePayload) {
auto authUserIDRust = jsiStringToRustString(authUserID, rt);
auto authDeviceIDRust = jsiStringToRustString(authDeviceID, rt);
auto authAccessTokenRust = jsiStringToRustString(authAccessToken, rt);
auto updatePayloadRust = jsiStringToRustString(updatePayload, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityUpdateDeviceList(
authUserIDRust,
authDeviceIDRust,
authAccessTokenRust,
updatePayloadRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
jsi::Value CommRustModule::uploadSecondaryDeviceKeysAndLogIn(
jsi::Runtime &rt,
jsi::String userID,
jsi::String challengeResponse,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) {
auto userIDRust = jsiStringToRustString(userID, rt);
auto challengeResponseRust = jsiStringToRustString(challengeResponse, rt);
auto keyPayloadRust = jsiStringToRustString(keyPayload, rt);
auto keyPayloadSignatureRust = jsiStringToRustString(keyPayloadSignature, rt);
auto contentPrekeyRust = jsiStringToRustString(contentPrekey, rt);
auto contentPrekeySignatureRust =
jsiStringToRustString(contentPrekeySignature, rt);
auto notifPrekeyRust = jsiStringToRustString(notifPrekey, rt);
auto notifPrekeySignatureRust =
jsiStringToRustString(notifPrekeySignature, rt);
auto contentOneTimeKeysRust = jsiStringArrayToRustVec(contentOneTimeKeys, rt);
auto notifOneTimeKeysRust = jsiStringArrayToRustVec(notifOneTimeKeys, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityUploadSecondaryDeviceKeysAndLogIn(
userIDRust,
challengeResponseRust,
keyPayloadRust,
keyPayloadSignatureRust,
contentPrekeyRust,
contentPrekeySignatureRust,
notifPrekeyRust,
notifPrekeySignatureRust,
contentOneTimeKeysRust,
notifOneTimeKeysRust,
currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
return jsi::Value::undefined();
}
jsi::Value CommRustModule::findUserIDForWalletAddress(
jsi::Runtime &rt,
jsi::String walletAddress) {
auto walletAddressRust = jsiStringToRustString(walletAddress, rt);
return createPromiseAsJSIValue(
rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
std::string error;
try {
auto currentID = RustPromiseManager::instance.addPromise(
{promise, this->jsInvoker_, innerRt});
identityFindUserIDForWalletAddress(walletAddressRust, currentID);
} catch (const std::exception &e) {
error = e.what();
};
if (!error.empty()) {
this->jsInvoker_->invokeAsync(
[error, promise]() { promise->reject(error); });
}
});
}
+jsi::Value
+CommRustModule::findUserIDForUsername(jsi::Runtime &rt, jsi::String username) {
+ auto usernameRust = jsiStringToRustString(username, rt);
+ return createPromiseAsJSIValue(
+ rt, [=, this](jsi::Runtime &innerRt, std::shared_ptr promise) {
+ std::string error;
+ try {
+ auto currentID = RustPromiseManager::instance.addPromise(
+ {promise, this->jsInvoker_, innerRt});
+ identityFindUserIDForUsername(usernameRust, currentID);
+ } catch (const std::exception &e) {
+ error = e.what();
+ };
+ if (!error.empty()) {
+ this->jsInvoker_->invokeAsync(
+ [error, promise]() { promise->reject(error); });
+ }
+ });
+}
+
} // namespace comm
diff --git a/native/cpp/CommonCpp/NativeModules/CommRustModule.h b/native/cpp/CommonCpp/NativeModules/CommRustModule.h
index 3056cf4d6..4236f039a 100644
--- a/native/cpp/CommonCpp/NativeModules/CommRustModule.h
+++ b/native/cpp/CommonCpp/NativeModules/CommRustModule.h
@@ -1,133 +1,135 @@
#pragma once
#include "../_generated/rustJSI.h"
#include
#include
#include
namespace comm {
namespace jsi = facebook::jsi;
class CommRustModule : public facebook::react::CommRustModuleSchemaCxxSpecJSI {
virtual jsi::Value generateNonce(jsi::Runtime &rt) override;
virtual jsi::Value registerPasswordUser(
jsi::Runtime &rt,
jsi::String username,
jsi::String password,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) override;
virtual jsi::Value logInPasswordUser(
jsi::Runtime &rt,
jsi::String username,
jsi::String password,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) override;
virtual jsi::Value registerWalletUser(
jsi::Runtime &rt,
jsi::String siweMessage,
jsi::String siweSignature,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) override;
virtual jsi::Value logInWalletUser(
jsi::Runtime &rt,
jsi::String siweMessage,
jsi::String siweSignature,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) override;
virtual jsi::Value updatePassword(
jsi::Runtime &rt,
jsi::String userID,
jsi::String deviceID,
jsi::String accessToken,
jsi::String password) override;
virtual jsi::Value deleteUser(
jsi::Runtime &rt,
jsi::String userID,
jsi::String deviceID,
jsi::String accessToken) override;
virtual jsi::Value getOutboundKeysForUser(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String userID) override;
virtual jsi::Value getInboundKeysForUser(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String userID) override;
virtual jsi::Value versionSupported(jsi::Runtime &rt) override;
virtual jsi::Value uploadOneTimeKeys(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::Array contentOneTimePreKeys,
jsi::Array notifOneTimePreKeys) override;
virtual jsi::Value getKeyserverKeys(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String keyserverID) override;
virtual jsi::Value getDeviceListForUser(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String userID,
std::optional sinceTimestamp) override;
virtual jsi::Value updateDeviceList(
jsi::Runtime &rt,
jsi::String authUserID,
jsi::String authDeviceID,
jsi::String authAccessToken,
jsi::String updatePayload) override;
virtual jsi::Value uploadSecondaryDeviceKeysAndLogIn(
jsi::Runtime &rt,
jsi::String userID,
jsi::String challengeResponse,
jsi::String keyPayload,
jsi::String keyPayloadSignature,
jsi::String contentPrekey,
jsi::String contentPrekeySignature,
jsi::String notifPrekey,
jsi::String notifPrekeySignature,
jsi::Array contentOneTimeKeys,
jsi::Array notifOneTimeKeys) override;
virtual jsi::Value findUserIDForWalletAddress(
jsi::Runtime &rt,
jsi::String walletAddress) override;
+ virtual jsi::Value
+ findUserIDForUsername(jsi::Runtime &rt, jsi::String username) override;
public:
CommRustModule(std::shared_ptr jsInvoker);
};
} // namespace comm
diff --git a/native/cpp/CommonCpp/_generated/rustJSI-generated.cpp b/native/cpp/CommonCpp/_generated/rustJSI-generated.cpp
index 0bc4de1f2..4ffa520a2 100644
--- a/native/cpp/CommonCpp/_generated/rustJSI-generated.cpp
+++ b/native/cpp/CommonCpp/_generated/rustJSI-generated.cpp
@@ -1,86 +1,90 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleH.js
*/
#include "rustJSI.h"
namespace facebook {
namespace react {
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_generateNonce(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->generateNonce(rt);
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_registerPasswordUser(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->registerPasswordUser(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt), args[4].asString(rt), args[5].asString(rt), args[6].asString(rt), args[7].asString(rt), args[8].asObject(rt).asArray(rt), args[9].asObject(rt).asArray(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_logInPasswordUser(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->logInPasswordUser(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt), args[4].asString(rt), args[5].asString(rt), args[6].asString(rt), args[7].asString(rt), args[8].asObject(rt).asArray(rt), args[9].asObject(rt).asArray(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_registerWalletUser(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->registerWalletUser(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt), args[4].asString(rt), args[5].asString(rt), args[6].asString(rt), args[7].asString(rt), args[8].asObject(rt).asArray(rt), args[9].asObject(rt).asArray(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_logInWalletUser(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->logInWalletUser(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt), args[4].asString(rt), args[5].asString(rt), args[6].asString(rt), args[7].asString(rt), args[8].asObject(rt).asArray(rt), args[9].asObject(rt).asArray(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_updatePassword(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->updatePassword(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_deleteUser(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->deleteUser(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_getOutboundKeysForUser(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->getOutboundKeysForUser(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_getInboundKeysForUser(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->getInboundKeysForUser(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_versionSupported(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->versionSupported(rt);
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_uploadOneTimeKeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->uploadOneTimeKeys(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asObject(rt).asArray(rt), args[4].asObject(rt).asArray(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_getKeyserverKeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->getKeyserverKeys(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_getDeviceListForUser(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->getDeviceListForUser(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt), args[4].isNull() || args[4].isUndefined() ? std::nullopt : std::make_optional(args[4].asNumber()));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_updateDeviceList(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->updateDeviceList(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_uploadSecondaryDeviceKeysAndLogIn(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->uploadSecondaryDeviceKeysAndLogIn(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt), args[4].asString(rt), args[5].asString(rt), args[6].asString(rt), args[7].asString(rt), args[8].asObject(rt).asArray(rt), args[9].asObject(rt).asArray(rt));
}
static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_findUserIDForWalletAddress(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast(&turboModule)->findUserIDForWalletAddress(rt, args[0].asString(rt));
}
+static jsi::Value __hostFunction_CommRustModuleSchemaCxxSpecJSI_findUserIDForUsername(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
+ return static_cast(&turboModule)->findUserIDForUsername(rt, args[0].asString(rt));
+}
CommRustModuleSchemaCxxSpecJSI::CommRustModuleSchemaCxxSpecJSI(std::shared_ptr jsInvoker)
: TurboModule("CommRustTurboModule", jsInvoker) {
methodMap_["generateNonce"] = MethodMetadata {0, __hostFunction_CommRustModuleSchemaCxxSpecJSI_generateNonce};
methodMap_["registerPasswordUser"] = MethodMetadata {10, __hostFunction_CommRustModuleSchemaCxxSpecJSI_registerPasswordUser};
methodMap_["logInPasswordUser"] = MethodMetadata {10, __hostFunction_CommRustModuleSchemaCxxSpecJSI_logInPasswordUser};
methodMap_["registerWalletUser"] = MethodMetadata {10, __hostFunction_CommRustModuleSchemaCxxSpecJSI_registerWalletUser};
methodMap_["logInWalletUser"] = MethodMetadata {10, __hostFunction_CommRustModuleSchemaCxxSpecJSI_logInWalletUser};
methodMap_["updatePassword"] = MethodMetadata {4, __hostFunction_CommRustModuleSchemaCxxSpecJSI_updatePassword};
methodMap_["deleteUser"] = MethodMetadata {3, __hostFunction_CommRustModuleSchemaCxxSpecJSI_deleteUser};
methodMap_["getOutboundKeysForUser"] = MethodMetadata {4, __hostFunction_CommRustModuleSchemaCxxSpecJSI_getOutboundKeysForUser};
methodMap_["getInboundKeysForUser"] = MethodMetadata {4, __hostFunction_CommRustModuleSchemaCxxSpecJSI_getInboundKeysForUser};
methodMap_["versionSupported"] = MethodMetadata {0, __hostFunction_CommRustModuleSchemaCxxSpecJSI_versionSupported};
methodMap_["uploadOneTimeKeys"] = MethodMetadata {5, __hostFunction_CommRustModuleSchemaCxxSpecJSI_uploadOneTimeKeys};
methodMap_["getKeyserverKeys"] = MethodMetadata {4, __hostFunction_CommRustModuleSchemaCxxSpecJSI_getKeyserverKeys};
methodMap_["getDeviceListForUser"] = MethodMetadata {5, __hostFunction_CommRustModuleSchemaCxxSpecJSI_getDeviceListForUser};
methodMap_["updateDeviceList"] = MethodMetadata {4, __hostFunction_CommRustModuleSchemaCxxSpecJSI_updateDeviceList};
methodMap_["uploadSecondaryDeviceKeysAndLogIn"] = MethodMetadata {10, __hostFunction_CommRustModuleSchemaCxxSpecJSI_uploadSecondaryDeviceKeysAndLogIn};
methodMap_["findUserIDForWalletAddress"] = MethodMetadata {1, __hostFunction_CommRustModuleSchemaCxxSpecJSI_findUserIDForWalletAddress};
+ methodMap_["findUserIDForUsername"] = MethodMetadata {1, __hostFunction_CommRustModuleSchemaCxxSpecJSI_findUserIDForUsername};
}
} // namespace react
} // namespace facebook
diff --git a/native/cpp/CommonCpp/_generated/rustJSI.h b/native/cpp/CommonCpp/_generated/rustJSI.h
index f71761613..36fffe449 100644
--- a/native/cpp/CommonCpp/_generated/rustJSI.h
+++ b/native/cpp/CommonCpp/_generated/rustJSI.h
@@ -1,197 +1,206 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleH.js
*/
#pragma once
#include
#include
namespace facebook {
namespace react {
class JSI_EXPORT CommRustModuleSchemaCxxSpecJSI : public TurboModule {
protected:
CommRustModuleSchemaCxxSpecJSI(std::shared_ptr jsInvoker);
public:
virtual jsi::Value generateNonce(jsi::Runtime &rt) = 0;
virtual jsi::Value registerPasswordUser(jsi::Runtime &rt, jsi::String username, jsi::String password, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) = 0;
virtual jsi::Value logInPasswordUser(jsi::Runtime &rt, jsi::String username, jsi::String password, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) = 0;
virtual jsi::Value registerWalletUser(jsi::Runtime &rt, jsi::String siweMessage, jsi::String siweSignature, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) = 0;
virtual jsi::Value logInWalletUser(jsi::Runtime &rt, jsi::String siweMessage, jsi::String siweSignature, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) = 0;
virtual jsi::Value updatePassword(jsi::Runtime &rt, jsi::String userID, jsi::String deviceID, jsi::String accessToken, jsi::String password) = 0;
virtual jsi::Value deleteUser(jsi::Runtime &rt, jsi::String userID, jsi::String deviceID, jsi::String accessToken) = 0;
virtual jsi::Value getOutboundKeysForUser(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String userID) = 0;
virtual jsi::Value getInboundKeysForUser(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String userID) = 0;
virtual jsi::Value versionSupported(jsi::Runtime &rt) = 0;
virtual jsi::Value uploadOneTimeKeys(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::Array contentOneTimePreKeys, jsi::Array notifOneTimePreKeys) = 0;
virtual jsi::Value getKeyserverKeys(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String keyserverID) = 0;
virtual jsi::Value getDeviceListForUser(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String userID, std::optional sinceTimestamp) = 0;
virtual jsi::Value updateDeviceList(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String updatePayload) = 0;
virtual jsi::Value uploadSecondaryDeviceKeysAndLogIn(jsi::Runtime &rt, jsi::String userID, jsi::String challengeResponse, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) = 0;
virtual jsi::Value findUserIDForWalletAddress(jsi::Runtime &rt, jsi::String walletAddress) = 0;
+ virtual jsi::Value findUserIDForUsername(jsi::Runtime &rt, jsi::String username) = 0;
};
template
class JSI_EXPORT CommRustModuleSchemaCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
}
protected:
CommRustModuleSchemaCxxSpec(std::shared_ptr jsInvoker)
: TurboModule("CommRustTurboModule", jsInvoker),
delegate_(static_cast(this), jsInvoker) {}
private:
class Delegate : public CommRustModuleSchemaCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr jsInvoker) :
CommRustModuleSchemaCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
jsi::Value generateNonce(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::generateNonce) == 1,
"Expected generateNonce(...) to have 1 parameters");
return bridging::callFromJs(
rt, &T::generateNonce, jsInvoker_, instance_);
}
jsi::Value registerPasswordUser(jsi::Runtime &rt, jsi::String username, jsi::String password, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) override {
static_assert(
bridging::getParameterCount(&T::registerPasswordUser) == 11,
"Expected registerPasswordUser(...) to have 11 parameters");
return bridging::callFromJs(
rt, &T::registerPasswordUser, jsInvoker_, instance_, std::move(username), std::move(password), std::move(keyPayload), std::move(keyPayloadSignature), std::move(contentPrekey), std::move(contentPrekeySignature), std::move(notifPrekey), std::move(notifPrekeySignature), std::move(contentOneTimeKeys), std::move(notifOneTimeKeys));
}
jsi::Value logInPasswordUser(jsi::Runtime &rt, jsi::String username, jsi::String password, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) override {
static_assert(
bridging::getParameterCount(&T::logInPasswordUser) == 11,
"Expected logInPasswordUser(...) to have 11 parameters");
return bridging::callFromJs(
rt, &T::logInPasswordUser, jsInvoker_, instance_, std::move(username), std::move(password), std::move(keyPayload), std::move(keyPayloadSignature), std::move(contentPrekey), std::move(contentPrekeySignature), std::move(notifPrekey), std::move(notifPrekeySignature), std::move(contentOneTimeKeys), std::move(notifOneTimeKeys));
}
jsi::Value registerWalletUser(jsi::Runtime &rt, jsi::String siweMessage, jsi::String siweSignature, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) override {
static_assert(
bridging::getParameterCount(&T::registerWalletUser) == 11,
"Expected registerWalletUser(...) to have 11 parameters");
return bridging::callFromJs(
rt, &T::registerWalletUser, jsInvoker_, instance_, std::move(siweMessage), std::move(siweSignature), std::move(keyPayload), std::move(keyPayloadSignature), std::move(contentPrekey), std::move(contentPrekeySignature), std::move(notifPrekey), std::move(notifPrekeySignature), std::move(contentOneTimeKeys), std::move(notifOneTimeKeys));
}
jsi::Value logInWalletUser(jsi::Runtime &rt, jsi::String siweMessage, jsi::String siweSignature, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) override {
static_assert(
bridging::getParameterCount(&T::logInWalletUser) == 11,
"Expected logInWalletUser(...) to have 11 parameters");
return bridging::callFromJs(
rt, &T::logInWalletUser, jsInvoker_, instance_, std::move(siweMessage), std::move(siweSignature), std::move(keyPayload), std::move(keyPayloadSignature), std::move(contentPrekey), std::move(contentPrekeySignature), std::move(notifPrekey), std::move(notifPrekeySignature), std::move(contentOneTimeKeys), std::move(notifOneTimeKeys));
}
jsi::Value updatePassword(jsi::Runtime &rt, jsi::String userID, jsi::String deviceID, jsi::String accessToken, jsi::String password) override {
static_assert(
bridging::getParameterCount(&T::updatePassword) == 5,
"Expected updatePassword(...) to have 5 parameters");
return bridging::callFromJs(
rt, &T::updatePassword, jsInvoker_, instance_, std::move(userID), std::move(deviceID), std::move(accessToken), std::move(password));
}
jsi::Value deleteUser(jsi::Runtime &rt, jsi::String userID, jsi::String deviceID, jsi::String accessToken) override {
static_assert(
bridging::getParameterCount(&T::deleteUser) == 4,
"Expected deleteUser(...) to have 4 parameters");
return bridging::callFromJs(
rt, &T::deleteUser, jsInvoker_, instance_, std::move(userID), std::move(deviceID), std::move(accessToken));
}
jsi::Value getOutboundKeysForUser(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String userID) override {
static_assert(
bridging::getParameterCount(&T::getOutboundKeysForUser) == 5,
"Expected getOutboundKeysForUser(...) to have 5 parameters");
return bridging::callFromJs(
rt, &T::getOutboundKeysForUser, jsInvoker_, instance_, std::move(authUserID), std::move(authDeviceID), std::move(authAccessToken), std::move(userID));
}
jsi::Value getInboundKeysForUser(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String userID) override {
static_assert(
bridging::getParameterCount(&T::getInboundKeysForUser) == 5,
"Expected getInboundKeysForUser(...) to have 5 parameters");
return bridging::callFromJs(
rt, &T::getInboundKeysForUser, jsInvoker_, instance_, std::move(authUserID), std::move(authDeviceID), std::move(authAccessToken), std::move(userID));
}
jsi::Value versionSupported(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::versionSupported) == 1,
"Expected versionSupported(...) to have 1 parameters");
return bridging::callFromJs(
rt, &T::versionSupported, jsInvoker_, instance_);
}
jsi::Value uploadOneTimeKeys(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::Array contentOneTimePreKeys, jsi::Array notifOneTimePreKeys) override {
static_assert(
bridging::getParameterCount(&T::uploadOneTimeKeys) == 6,
"Expected uploadOneTimeKeys(...) to have 6 parameters");
return bridging::callFromJs(
rt, &T::uploadOneTimeKeys, jsInvoker_, instance_, std::move(authUserID), std::move(authDeviceID), std::move(authAccessToken), std::move(contentOneTimePreKeys), std::move(notifOneTimePreKeys));
}
jsi::Value getKeyserverKeys(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String keyserverID) override {
static_assert(
bridging::getParameterCount(&T::getKeyserverKeys) == 5,
"Expected getKeyserverKeys(...) to have 5 parameters");
return bridging::callFromJs(
rt, &T::getKeyserverKeys, jsInvoker_, instance_, std::move(authUserID), std::move(authDeviceID), std::move(authAccessToken), std::move(keyserverID));
}
jsi::Value getDeviceListForUser(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String userID, std::optional sinceTimestamp) override {
static_assert(
bridging::getParameterCount(&T::getDeviceListForUser) == 6,
"Expected getDeviceListForUser(...) to have 6 parameters");
return bridging::callFromJs(
rt, &T::getDeviceListForUser, jsInvoker_, instance_, std::move(authUserID), std::move(authDeviceID), std::move(authAccessToken), std::move(userID), std::move(sinceTimestamp));
}
jsi::Value updateDeviceList(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken, jsi::String updatePayload) override {
static_assert(
bridging::getParameterCount(&T::updateDeviceList) == 5,
"Expected updateDeviceList(...) to have 5 parameters");
return bridging::callFromJs(
rt, &T::updateDeviceList, jsInvoker_, instance_, std::move(authUserID), std::move(authDeviceID), std::move(authAccessToken), std::move(updatePayload));
}
jsi::Value uploadSecondaryDeviceKeysAndLogIn(jsi::Runtime &rt, jsi::String userID, jsi::String challengeResponse, jsi::String keyPayload, jsi::String keyPayloadSignature, jsi::String contentPrekey, jsi::String contentPrekeySignature, jsi::String notifPrekey, jsi::String notifPrekeySignature, jsi::Array contentOneTimeKeys, jsi::Array notifOneTimeKeys) override {
static_assert(
bridging::getParameterCount(&T::uploadSecondaryDeviceKeysAndLogIn) == 11,
"Expected uploadSecondaryDeviceKeysAndLogIn(...) to have 11 parameters");
return bridging::callFromJs(
rt, &T::uploadSecondaryDeviceKeysAndLogIn, jsInvoker_, instance_, std::move(userID), std::move(challengeResponse), std::move(keyPayload), std::move(keyPayloadSignature), std::move(contentPrekey), std::move(contentPrekeySignature), std::move(notifPrekey), std::move(notifPrekeySignature), std::move(contentOneTimeKeys), std::move(notifOneTimeKeys));
}
jsi::Value findUserIDForWalletAddress(jsi::Runtime &rt, jsi::String walletAddress) override {
static_assert(
bridging::getParameterCount(&T::findUserIDForWalletAddress) == 2,
"Expected findUserIDForWalletAddress(...) to have 2 parameters");
return bridging::callFromJs(
rt, &T::findUserIDForWalletAddress, jsInvoker_, instance_, std::move(walletAddress));
}
+ jsi::Value findUserIDForUsername(jsi::Runtime &rt, jsi::String username) override {
+ static_assert(
+ bridging::getParameterCount(&T::findUserIDForUsername) == 2,
+ "Expected findUserIDForUsername(...) to have 2 parameters");
+
+ return bridging::callFromJs(
+ rt, &T::findUserIDForUsername, jsInvoker_, instance_, std::move(username));
+ }
private:
T *instance_;
};
Delegate delegate_;
};
} // namespace react
} // namespace facebook
diff --git a/native/native_rust_library/src/exact_user_search.rs b/native/native_rust_library/src/exact_user_search.rs
index a651a8034..edec1fa30 100644
--- a/native/native_rust_library/src/exact_user_search.rs
+++ b/native/native_rust_library/src/exact_user_search.rs
@@ -1,54 +1,68 @@
use crate::{
handle_string_result_as_callback, Error, CODE_VERSION, DEVICE_TYPE,
IDENTITY_SOCKET_ADDR, RUNTIME,
};
+use find_user_id_request::Identifier as RequestIdentifier;
use grpc_clients::identity::{
get_unauthenticated_client,
protos::unauth::{find_user_id_request, FindUserIdRequest},
};
use serde::Serialize;
use tracing::instrument;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct FindUserIDResponse {
#[serde(rename = "userID")]
user_id: Option,
+ #[serde(rename = "isReserved")]
is_reserved: bool,
}
#[instrument]
pub fn find_user_id_for_wallet_address(
wallet_address: String,
promise_id: u32,
) {
RUNTIME.spawn(async move {
- let result = find_user_id_helper(wallet_address).await;
+ let result =
+ find_user_id_helper(RequestIdentifier::WalletAddress(wallet_address))
+ .await;
handle_string_result_as_callback(result, promise_id);
});
}
-async fn find_user_id_helper(wallet_address: String) -> Result {
- use find_user_id_request::Identifier as RequestIdentifier;
+#[instrument]
+pub fn find_user_id_for_username(username: String, promise_id: u32) {
+ RUNTIME.spawn(async move {
+ let result =
+ find_user_id_helper(RequestIdentifier::Username(username)).await;
+ handle_string_result_as_callback(result, promise_id);
+ });
+}
+
+async fn find_user_id_helper(
+ identifier: RequestIdentifier,
+) -> Result {
let find_user_id_request = FindUserIdRequest {
- identifier: Some(RequestIdentifier::WalletAddress(wallet_address)),
+ identifier: Some(identifier),
};
let mut identity_client = get_unauthenticated_client(
IDENTITY_SOCKET_ADDR,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let response = identity_client
.find_user_id(find_user_id_request)
.await?
.into_inner();
let find_user_id_response = FindUserIDResponse {
user_id: response.user_id,
is_reserved: response.is_reserved,
};
Ok(serde_json::to_string(&find_user_id_response)?)
}
diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs
index 0e3b16661..b2362f290 100644
--- a/native/native_rust_library/src/lib.rs
+++ b/native/native_rust_library/src/lib.rs
@@ -1,1451 +1,1456 @@
use backup::ffi::*;
use comm_opaque2::client::{Login, Registration};
use comm_opaque2::grpc::opaque_error_to_grpc_status as handle_error;
-use exact_user_search::find_user_id_for_wallet_address;
+use exact_user_search::{
+ find_user_id_for_username, find_user_id_for_wallet_address,
+};
use ffi::{bool_callback, string_callback, void_callback};
use future_manager::ffi::*;
use grpc_clients::identity::protos::auth::{
GetDeviceListRequest, UpdateDeviceListRequest,
};
use grpc_clients::identity::protos::authenticated::{
InboundKeyInfo, InboundKeysForUserRequest, KeyserverKeysResponse,
OutboundKeyInfo, OutboundKeysForUserRequest, RefreshUserPrekeysRequest,
UpdateUserPasswordFinishRequest, UpdateUserPasswordStartRequest,
UploadOneTimeKeysRequest,
};
use grpc_clients::identity::protos::unauth::{
AuthResponse, DeviceKeyUpload, DeviceType, Empty, IdentityKeyInfo,
OpaqueLoginFinishRequest, OpaqueLoginStartRequest, Prekey,
RegistrationFinishRequest, RegistrationStartRequest,
SecondaryDeviceKeysUploadRequest, WalletAuthRequest,
};
use grpc_clients::identity::{get_auth_client, get_unauthenticated_client};
use lazy_static::lazy_static;
use serde::Serialize;
use std::sync::Arc;
use tokio::runtime::{Builder, Runtime};
use tonic::Status;
use tracing::instrument;
use wallet_registration::register_wallet_user;
mod argon2_tools;
mod backup;
mod constants;
mod exact_user_search;
mod future_manager;
mod wallet_registration;
use argon2_tools::compute_backup_key_str;
mod generated {
// We get the CODE_VERSION from this generated file
include!(concat!(env!("OUT_DIR"), "/version.rs"));
// We get the IDENTITY_SOCKET_ADDR from this generated file
include!(concat!(env!("OUT_DIR"), "/socket_config.rs"));
}
pub use generated::CODE_VERSION;
pub use generated::{BACKUP_SOCKET_ADDR, IDENTITY_SOCKET_ADDR};
#[cfg(not(target_os = "android"))]
pub const DEVICE_TYPE: DeviceType = DeviceType::Ios;
#[cfg(target_os = "android")]
pub const DEVICE_TYPE: DeviceType = DeviceType::Android;
lazy_static! {
static ref RUNTIME: Arc =
Arc::new(Builder::new_multi_thread().enable_all().build().unwrap());
}
#[cxx::bridge]
mod ffi {
extern "Rust" {
#[cxx_name = "identityRegisterPasswordUser"]
fn register_password_user(
username: String,
password: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
);
#[cxx_name = "identityLogInPasswordUser"]
fn log_in_password_user(
username: String,
password: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
);
#[cxx_name = "identityRegisterWalletUser"]
fn register_wallet_user(
siwe_message: String,
siwe_signature: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
);
#[cxx_name = "identityLogInWalletUser"]
fn log_in_wallet_user(
siwe_message: String,
siwe_signature: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
);
#[cxx_name = "identityUpdateUserPassword"]
fn update_user_password(
user_id: String,
device_id: String,
access_token: String,
password: String,
promise_id: u32,
);
#[cxx_name = "identityDeleteUser"]
fn delete_user(
user_id: String,
device_id: String,
access_token: String,
promise_id: u32,
);
#[cxx_name = "identityGetOutboundKeysForUser"]
fn get_outbound_keys_for_user(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
user_id: String,
promise_id: u32,
);
#[cxx_name = "identityGetInboundKeysForUser"]
fn get_inbound_keys_for_user(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
user_id: String,
promise_id: u32,
);
#[cxx_name = "identityRefreshUserPrekeys"]
fn refresh_user_prekeys(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
promise_id: u32,
);
#[cxx_name = "identityGenerateNonce"]
fn generate_nonce(promise_id: u32);
#[cxx_name = "identityVersionSupported"]
fn version_supported(promise_id: u32);
#[cxx_name = "identityUploadOneTimeKeys"]
fn upload_one_time_keys(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
);
#[cxx_name = "identityGetKeyserverKeys"]
fn get_keyserver_keys(
user_id: String,
device_id: String,
access_token: String,
keyserver_id: String,
promise_id: u32,
);
#[cxx_name = "identityGetDeviceListForUser"]
fn get_device_list_for_user(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
user_id: String,
since_timestamp: i64,
promise_id: u32,
);
#[cxx_name = "identityUpdateDeviceList"]
fn update_device_list(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
update_payload: String,
promise_id: u32,
);
#[cxx_name = "identityUploadSecondaryDeviceKeysAndLogIn"]
fn upload_secondary_device_keys_and_log_in(
user_id: String,
challenge_response: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
);
#[cxx_name = "identityFindUserIDForWalletAddress"]
fn find_user_id_for_wallet_address(wallet_address: String, promise_id: u32);
+ #[cxx_name = "identityFindUserIDForUsername"]
+ fn find_user_id_for_username(username: String, promise_id: u32);
+
// Argon2
#[cxx_name = "compute_backup_key"]
fn compute_backup_key_str(
password: &str,
backup_id: &str,
) -> Result<[u8; 32]>;
}
unsafe extern "C++" {
include!("RustCallback.h");
#[namespace = "comm"]
#[cxx_name = "stringCallback"]
fn string_callback(error: String, promise_id: u32, ret: String);
#[namespace = "comm"]
#[cxx_name = "voidCallback"]
fn void_callback(error: String, promise_id: u32);
#[namespace = "comm"]
#[cxx_name = "boolCallback"]
fn bool_callback(error: String, promise_id: u32, ret: bool);
}
// AES cryptography
#[namespace = "comm"]
unsafe extern "C++" {
include!("RustAESCrypto.h");
#[allow(unused)]
#[cxx_name = "aesGenerateKey"]
fn generate_key(buffer: &mut [u8]) -> Result<()>;
/// The first two argument aren't mutated but creation of Java ByteBuffer
/// requires the underlying bytes to be mutable.
#[allow(unused)]
#[cxx_name = "aesEncrypt"]
fn encrypt(
key: &mut [u8],
plaintext: &mut [u8],
sealed_data: &mut [u8],
) -> Result<()>;
/// The first two argument aren't mutated but creation of Java ByteBuffer
/// requires the underlying bytes to be mutable.
#[allow(unused)]
#[cxx_name = "aesDecrypt"]
fn decrypt(
key: &mut [u8],
sealed_data: &mut [u8],
plaintext: &mut [u8],
) -> Result<()>;
}
// Comm Services Auth Metadata Emission
#[namespace = "comm"]
unsafe extern "C++" {
include!("RustCSAMetadataEmitter.h");
#[allow(unused)]
#[cxx_name = "sendAuthMetadataToJS"]
fn send_auth_metadata_to_js(
access_token: String,
user_id: String,
) -> Result<()>;
}
// Backup
extern "Rust" {
#[cxx_name = "startBackupHandler"]
fn start_backup_handler() -> Result<()>;
#[cxx_name = "stopBackupHandler"]
fn stop_backup_handler() -> Result<()>;
#[cxx_name = "triggerBackupFileUpload"]
fn trigger_backup_file_upload();
#[cxx_name = "createBackup"]
fn create_backup(
backup_id: String,
backup_secret: String,
pickle_key: String,
pickled_account: String,
promise_id: u32,
);
#[cxx_name = "restoreBackup"]
fn restore_backup(backup_secret: String, promise_id: u32);
}
// Secure store
#[namespace = "comm"]
unsafe extern "C++" {
include!("RustSecureStore.h");
#[allow(unused)]
#[cxx_name = "secureStoreSet"]
fn secure_store_set(key: &str, value: String) -> Result<()>;
#[cxx_name = "secureStoreGet"]
fn secure_store_get(key: &str) -> Result;
}
// C++ Backup creation
#[namespace = "comm"]
unsafe extern "C++" {
include!("RustBackupExecutor.h");
#[cxx_name = "getBackupDirectoryPath"]
fn get_backup_directory_path() -> Result;
#[cxx_name = "getBackupFilePath"]
fn get_backup_file_path(
backup_id: &str,
is_attachments: bool,
) -> Result;
#[cxx_name = "getBackupLogFilePath"]
fn get_backup_log_file_path(
backup_id: &str,
log_id: &str,
is_attachments: bool,
) -> Result;
#[cxx_name = "getBackupUserKeysFilePath"]
fn get_backup_user_keys_file_path(backup_id: &str) -> Result;
#[cxx_name = "createMainCompaction"]
fn create_main_compaction(backup_id: &str, future_id: usize);
#[cxx_name = "restoreFromMainCompaction"]
fn restore_from_main_compaction(
main_compaction_path: &str,
main_compaction_encryption_key: &str,
future_id: usize,
);
#[cxx_name = "restoreFromBackupLog"]
fn restore_from_backup_log(backup_log: Vec, future_id: usize);
}
// Future handling from C++
extern "Rust" {
#[cxx_name = "resolveUnitFuture"]
fn resolve_unit_future(future_id: usize);
#[cxx_name = "rejectFuture"]
fn reject_future(future_id: usize, error: String);
}
}
fn handle_string_result_as_callback(
result: Result,
promise_id: u32,
) where
E: std::fmt::Display,
{
match result {
Err(e) => string_callback(e.to_string(), promise_id, "".to_string()),
Ok(r) => string_callback("".to_string(), promise_id, r),
}
}
fn handle_void_result_as_callback(result: Result<(), E>, promise_id: u32)
where
E: std::fmt::Display,
{
match result {
Err(e) => void_callback(e.to_string(), promise_id),
Ok(_) => void_callback("".to_string(), promise_id),
}
}
fn handle_bool_result_as_callback(result: Result, promise_id: u32)
where
E: std::fmt::Display,
{
match result {
Err(e) => bool_callback(e.to_string(), promise_id, false),
Ok(r) => bool_callback("".to_string(), promise_id, r),
}
}
fn generate_nonce(promise_id: u32) {
RUNTIME.spawn(async move {
let result = fetch_nonce().await;
handle_string_result_as_callback(result, promise_id);
});
}
async fn fetch_nonce() -> Result {
let mut identity_client = get_unauthenticated_client(
IDENTITY_SOCKET_ADDR,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let nonce = identity_client
.generate_nonce(Empty {})
.await?
.into_inner()
.nonce;
Ok(nonce)
}
fn version_supported(promise_id: u32) {
RUNTIME.spawn(async move {
let result = version_supported_helper().await;
handle_bool_result_as_callback(result, promise_id);
});
}
async fn version_supported_helper() -> Result {
let mut identity_client = get_unauthenticated_client(
IDENTITY_SOCKET_ADDR,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let response = identity_client.ping(Empty {}).await;
match response {
Ok(_) => Ok(true),
Err(e) => {
if grpc_clients::error::is_version_unsupported(&e) {
Ok(false)
} else {
Err(e.into())
}
}
}
}
fn get_keyserver_keys(
user_id: String,
device_id: String,
access_token: String,
keyserver_id: String,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let get_keyserver_keys_request = OutboundKeysForUserRequest {
user_id: keyserver_id,
};
let auth_info = AuthInfo {
access_token,
user_id,
device_id,
};
let result =
get_keyserver_keys_helper(get_keyserver_keys_request, auth_info).await;
handle_string_result_as_callback(result, promise_id);
});
}
async fn get_keyserver_keys_helper(
get_keyserver_keys_request: OutboundKeysForUserRequest,
auth_info: AuthInfo,
) -> Result {
let mut identity_client = get_auth_client(
IDENTITY_SOCKET_ADDR,
auth_info.user_id,
auth_info.device_id,
auth_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let response = identity_client
.get_keyserver_keys(get_keyserver_keys_request)
.await?
.into_inner();
let keyserver_keys = OutboundKeyInfoResponse::try_from(response)?;
Ok(serde_json::to_string(&keyserver_keys)?)
}
struct AuthInfo {
user_id: String,
device_id: String,
access_token: String,
}
#[instrument]
fn register_password_user(
username: String,
password: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let password_user_info = PasswordUserInfo {
username,
password,
key_payload,
key_payload_signature,
content_prekey,
content_prekey_signature,
notif_prekey,
notif_prekey_signature,
content_one_time_keys,
notif_one_time_keys,
};
let result = register_password_user_helper(password_user_info).await;
handle_string_result_as_callback(result, promise_id);
});
}
struct PasswordUserInfo {
username: String,
password: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct UserIDAndDeviceAccessToken {
#[serde(rename = "userID")]
user_id: String,
access_token: String,
}
impl From for UserIDAndDeviceAccessToken {
fn from(value: AuthResponse) -> Self {
let AuthResponse {
user_id,
access_token,
} = value;
Self {
user_id,
access_token,
}
}
}
async fn register_password_user_helper(
password_user_info: PasswordUserInfo,
) -> Result {
let mut client_registration = Registration::new();
let opaque_registration_request = client_registration
.start(&password_user_info.password)
.map_err(handle_error)?;
let registration_start_request = RegistrationStartRequest {
opaque_registration_request,
username: password_user_info.username,
device_key_upload: Some(DeviceKeyUpload {
device_key_info: Some(IdentityKeyInfo {
payload: password_user_info.key_payload,
payload_signature: password_user_info.key_payload_signature,
social_proof: None,
}),
content_upload: Some(Prekey {
prekey: password_user_info.content_prekey,
prekey_signature: password_user_info.content_prekey_signature,
}),
notif_upload: Some(Prekey {
prekey: password_user_info.notif_prekey,
prekey_signature: password_user_info.notif_prekey_signature,
}),
one_time_content_prekeys: password_user_info.content_one_time_keys,
one_time_notif_prekeys: password_user_info.notif_one_time_keys,
device_type: DEVICE_TYPE.into(),
}),
};
let mut identity_client = get_unauthenticated_client(
IDENTITY_SOCKET_ADDR,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let response = identity_client
.register_password_user_start(registration_start_request)
.await?;
let registration_start_response = response.into_inner();
let opaque_registration_upload = client_registration
.finish(
&password_user_info.password,
®istration_start_response.opaque_registration_response,
)
.map_err(handle_error)?;
let registration_finish_request = RegistrationFinishRequest {
session_id: registration_start_response.session_id,
opaque_registration_upload,
};
let registration_finish_response = identity_client
.register_password_user_finish(registration_finish_request)
.await?
.into_inner();
let user_id_and_access_token =
UserIDAndDeviceAccessToken::from(registration_finish_response);
Ok(serde_json::to_string(&user_id_and_access_token)?)
}
#[instrument]
fn log_in_password_user(
username: String,
password: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let password_user_info = PasswordUserInfo {
username,
password,
key_payload,
key_payload_signature,
content_prekey,
content_prekey_signature,
notif_prekey,
notif_prekey_signature,
content_one_time_keys,
notif_one_time_keys,
};
let result = log_in_password_user_helper(password_user_info).await;
handle_string_result_as_callback(result, promise_id);
});
}
async fn log_in_password_user_helper(
password_user_info: PasswordUserInfo,
) -> Result {
let mut client_login = Login::new();
let opaque_login_request = client_login
.start(&password_user_info.password)
.map_err(handle_error)?;
let login_start_request = OpaqueLoginStartRequest {
opaque_login_request,
username: password_user_info.username,
device_key_upload: Some(DeviceKeyUpload {
device_key_info: Some(IdentityKeyInfo {
payload: password_user_info.key_payload,
payload_signature: password_user_info.key_payload_signature,
social_proof: None,
}),
content_upload: Some(Prekey {
prekey: password_user_info.content_prekey,
prekey_signature: password_user_info.content_prekey_signature,
}),
notif_upload: Some(Prekey {
prekey: password_user_info.notif_prekey,
prekey_signature: password_user_info.notif_prekey_signature,
}),
one_time_content_prekeys: password_user_info.content_one_time_keys,
one_time_notif_prekeys: password_user_info.notif_one_time_keys,
device_type: DEVICE_TYPE.into(),
}),
force: None,
};
let mut identity_client = get_unauthenticated_client(
IDENTITY_SOCKET_ADDR,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let response = identity_client
.log_in_password_user_start(login_start_request)
.await?;
let login_start_response = response.into_inner();
let opaque_login_upload = client_login
.finish(&login_start_response.opaque_login_response)
.map_err(handle_error)?;
let login_finish_request = OpaqueLoginFinishRequest {
session_id: login_start_response.session_id,
opaque_login_upload,
};
let login_finish_response = identity_client
.log_in_password_user_finish(login_finish_request)
.await?
.into_inner();
let user_id_and_access_token =
UserIDAndDeviceAccessToken::from(login_finish_response);
Ok(serde_json::to_string(&user_id_and_access_token)?)
}
struct WalletUserInfo {
siwe_message: String,
siwe_signature: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
}
#[instrument]
fn log_in_wallet_user(
siwe_message: String,
siwe_signature: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let wallet_user_info = WalletUserInfo {
siwe_message,
siwe_signature,
key_payload,
key_payload_signature,
content_prekey,
content_prekey_signature,
notif_prekey,
notif_prekey_signature,
content_one_time_keys,
notif_one_time_keys,
};
let result = log_in_wallet_user_helper(wallet_user_info).await;
handle_string_result_as_callback(result, promise_id);
});
}
async fn log_in_wallet_user_helper(
wallet_user_info: WalletUserInfo,
) -> Result {
let login_request = WalletAuthRequest {
siwe_message: wallet_user_info.siwe_message,
siwe_signature: wallet_user_info.siwe_signature,
device_key_upload: Some(DeviceKeyUpload {
device_key_info: Some(IdentityKeyInfo {
payload: wallet_user_info.key_payload,
payload_signature: wallet_user_info.key_payload_signature,
social_proof: None, // The SIWE message and signature are the social proof
}),
content_upload: Some(Prekey {
prekey: wallet_user_info.content_prekey,
prekey_signature: wallet_user_info.content_prekey_signature,
}),
notif_upload: Some(Prekey {
prekey: wallet_user_info.notif_prekey,
prekey_signature: wallet_user_info.notif_prekey_signature,
}),
one_time_content_prekeys: wallet_user_info.content_one_time_keys,
one_time_notif_prekeys: wallet_user_info.notif_one_time_keys,
device_type: DEVICE_TYPE.into(),
}),
};
let mut identity_client = get_unauthenticated_client(
IDENTITY_SOCKET_ADDR,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let login_response = identity_client
.log_in_wallet_user(login_request)
.await?
.into_inner();
let user_id_and_access_token =
UserIDAndDeviceAccessToken::from(login_response);
Ok(serde_json::to_string(&user_id_and_access_token)?)
}
struct UpdatePasswordInfo {
user_id: String,
device_id: String,
access_token: String,
password: String,
}
fn update_user_password(
user_id: String,
device_id: String,
access_token: String,
password: String,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let update_password_info = UpdatePasswordInfo {
access_token,
user_id,
device_id,
password,
};
let result = update_user_password_helper(update_password_info).await;
handle_void_result_as_callback(result, promise_id);
});
}
async fn update_user_password_helper(
update_password_info: UpdatePasswordInfo,
) -> Result<(), Error> {
let mut client_registration = Registration::new();
let opaque_registration_request = client_registration
.start(&update_password_info.password)
.map_err(handle_error)?;
let update_password_start_request = UpdateUserPasswordStartRequest {
opaque_registration_request,
};
let mut identity_client = get_auth_client(
IDENTITY_SOCKET_ADDR,
update_password_info.user_id,
update_password_info.device_id,
update_password_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let response = identity_client
.update_user_password_start(update_password_start_request)
.await?;
let update_password_start_response = response.into_inner();
let opaque_registration_upload = client_registration
.finish(
&update_password_info.password,
&update_password_start_response.opaque_registration_response,
)
.map_err(handle_error)?;
let update_password_finish_request = UpdateUserPasswordFinishRequest {
session_id: update_password_start_response.session_id,
opaque_registration_upload,
};
identity_client
.update_user_password_finish(update_password_finish_request)
.await?;
Ok(())
}
fn delete_user(
user_id: String,
device_id: String,
access_token: String,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let auth_info = AuthInfo {
access_token,
user_id,
device_id,
};
let result = delete_user_helper(auth_info).await;
handle_void_result_as_callback(result, promise_id);
});
}
async fn delete_user_helper(auth_info: AuthInfo) -> Result<(), Error> {
let mut identity_client = get_auth_client(
IDENTITY_SOCKET_ADDR,
auth_info.user_id,
auth_info.device_id,
auth_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
identity_client.delete_user(Empty {}).await?;
Ok(())
}
struct GetOutboundKeysRequestInfo {
user_id: String,
}
struct GetInboundKeysRequestInfo {
user_id: String,
}
// This struct should not be altered without also updating
// OutboundKeyInfoResponse in lib/types/identity-service-types.js
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct OutboundKeyInfoResponse {
pub payload: String,
pub payload_signature: String,
pub social_proof: Option,
pub content_prekey: String,
pub content_prekey_signature: String,
pub notif_prekey: String,
pub notif_prekey_signature: String,
pub one_time_content_prekey: Option,
pub one_time_notif_prekey: Option,
}
// This struct should not be altered without also updating
// InboundKeyInfoResponse in lib/types/identity-service-types.js
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct InboundKeyInfoResponse {
pub payload: String,
pub payload_signature: String,
pub social_proof: Option,
pub content_prekey: String,
pub content_prekey_signature: String,
pub notif_prekey: String,
pub notif_prekey_signature: String,
}
impl TryFrom for OutboundKeyInfoResponse {
type Error = Error;
fn try_from(key_info: OutboundKeyInfo) -> Result {
let identity_info =
key_info.identity_info.ok_or(Error::MissingResponseData)?;
let IdentityKeyInfo {
payload,
payload_signature,
social_proof,
} = identity_info;
let content_prekey =
key_info.content_prekey.ok_or(Error::MissingResponseData)?;
let Prekey {
prekey: content_prekey_value,
prekey_signature: content_prekey_signature,
} = content_prekey;
let notif_prekey =
key_info.notif_prekey.ok_or(Error::MissingResponseData)?;
let Prekey {
prekey: notif_prekey_value,
prekey_signature: notif_prekey_signature,
} = notif_prekey;
let one_time_content_prekey = key_info.one_time_content_prekey;
let one_time_notif_prekey = key_info.one_time_notif_prekey;
Ok(Self {
payload,
payload_signature,
social_proof,
content_prekey: content_prekey_value,
content_prekey_signature,
notif_prekey: notif_prekey_value,
notif_prekey_signature,
one_time_content_prekey,
one_time_notif_prekey,
})
}
}
impl TryFrom for OutboundKeyInfoResponse {
type Error = Error;
fn try_from(response: KeyserverKeysResponse) -> Result {
let key_info = response.keyserver_info.ok_or(Error::MissingResponseData)?;
Self::try_from(key_info)
}
}
fn get_outbound_keys_for_user(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
user_id: String,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let get_outbound_keys_request_info = GetOutboundKeysRequestInfo { user_id };
let auth_info = AuthInfo {
access_token: auth_access_token,
user_id: auth_user_id,
device_id: auth_device_id,
};
let result = get_outbound_keys_for_user_helper(
get_outbound_keys_request_info,
auth_info,
)
.await;
handle_string_result_as_callback(result, promise_id);
});
}
async fn get_outbound_keys_for_user_helper(
get_outbound_keys_request_info: GetOutboundKeysRequestInfo,
auth_info: AuthInfo,
) -> Result {
let mut identity_client = get_auth_client(
IDENTITY_SOCKET_ADDR,
auth_info.user_id,
auth_info.device_id,
auth_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let response = identity_client
.get_outbound_keys_for_user(OutboundKeysForUserRequest {
user_id: get_outbound_keys_request_info.user_id,
})
.await?
.into_inner();
let outbound_key_info: Vec = response
.devices
.into_values()
.map(OutboundKeyInfoResponse::try_from)
.collect::, _>>()?;
Ok(serde_json::to_string(&outbound_key_info)?)
}
impl TryFrom for InboundKeyInfoResponse {
type Error = Error;
fn try_from(key_info: InboundKeyInfo) -> Result {
let identity_info =
key_info.identity_info.ok_or(Error::MissingResponseData)?;
let IdentityKeyInfo {
payload,
payload_signature,
social_proof,
} = identity_info;
let content_prekey =
key_info.content_prekey.ok_or(Error::MissingResponseData)?;
let Prekey {
prekey: content_prekey_value,
prekey_signature: content_prekey_signature,
} = content_prekey;
let notif_prekey =
key_info.notif_prekey.ok_or(Error::MissingResponseData)?;
let Prekey {
prekey: notif_prekey_value,
prekey_signature: notif_prekey_signature,
} = notif_prekey;
Ok(Self {
payload,
payload_signature,
social_proof,
content_prekey: content_prekey_value,
content_prekey_signature,
notif_prekey: notif_prekey_value,
notif_prekey_signature,
})
}
}
fn get_inbound_keys_for_user(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
user_id: String,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let get_inbound_keys_request_info = GetInboundKeysRequestInfo { user_id };
let auth_info = AuthInfo {
access_token: auth_access_token,
user_id: auth_user_id,
device_id: auth_device_id,
};
let result = get_inbound_keys_for_user_helper(
get_inbound_keys_request_info,
auth_info,
)
.await;
handle_string_result_as_callback(result, promise_id);
});
}
async fn get_inbound_keys_for_user_helper(
get_inbound_keys_request_info: GetInboundKeysRequestInfo,
auth_info: AuthInfo,
) -> Result {
let mut identity_client = get_auth_client(
IDENTITY_SOCKET_ADDR,
auth_info.user_id,
auth_info.device_id,
auth_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let response = identity_client
.get_inbound_keys_for_user(InboundKeysForUserRequest {
user_id: get_inbound_keys_request_info.user_id,
})
.await?
.into_inner();
let inbound_key_info: Vec = response
.devices
.into_values()
.map(InboundKeyInfoResponse::try_from)
.collect::, _>>()?;
Ok(serde_json::to_string(&inbound_key_info)?)
}
fn refresh_user_prekeys(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let refresh_request = RefreshUserPrekeysRequest {
new_content_prekeys: Some(Prekey {
prekey: content_prekey,
prekey_signature: content_prekey_signature,
}),
new_notif_prekeys: Some(Prekey {
prekey: notif_prekey,
prekey_signature: notif_prekey_signature,
}),
};
let auth_info = AuthInfo {
access_token: auth_access_token,
user_id: auth_user_id,
device_id: auth_device_id,
};
let result = refresh_user_prekeys_helper(refresh_request, auth_info).await;
handle_void_result_as_callback(result, promise_id);
});
}
async fn refresh_user_prekeys_helper(
refresh_request: RefreshUserPrekeysRequest,
auth_info: AuthInfo,
) -> Result<(), Error> {
get_auth_client(
IDENTITY_SOCKET_ADDR,
auth_info.user_id,
auth_info.device_id,
auth_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?
.refresh_user_prekeys(refresh_request)
.await?;
Ok(())
}
#[instrument]
fn upload_one_time_keys(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let upload_request = UploadOneTimeKeysRequest {
content_one_time_prekeys: content_one_time_keys,
notif_one_time_prekeys: notif_one_time_keys,
};
let auth_info = AuthInfo {
access_token: auth_access_token,
user_id: auth_user_id,
device_id: auth_device_id,
};
let result = upload_one_time_keys_helper(auth_info, upload_request).await;
handle_void_result_as_callback(result, promise_id);
});
}
async fn upload_one_time_keys_helper(
auth_info: AuthInfo,
upload_request: UploadOneTimeKeysRequest,
) -> Result<(), Error> {
let mut identity_client = get_auth_client(
IDENTITY_SOCKET_ADDR,
auth_info.user_id,
auth_info.device_id,
auth_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
identity_client.upload_one_time_keys(upload_request).await?;
Ok(())
}
fn get_device_list_for_user(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
user_id: String,
since_timestamp: i64,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let auth_info = AuthInfo {
access_token: auth_access_token,
user_id: auth_user_id,
device_id: auth_device_id,
};
let since_timestamp = Option::from(since_timestamp).filter(|&t| t > 0);
let result =
get_device_list_for_user_helper(auth_info, user_id, since_timestamp)
.await;
handle_string_result_as_callback(result, promise_id);
});
}
async fn get_device_list_for_user_helper(
auth_info: AuthInfo,
user_id: String,
since_timestamp: Option,
) -> Result {
let mut identity_client = get_auth_client(
IDENTITY_SOCKET_ADDR,
auth_info.user_id,
auth_info.device_id,
auth_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let response = identity_client
.get_device_list_for_user(GetDeviceListRequest {
user_id,
since_timestamp,
})
.await?
.into_inner();
let payload = serde_json::to_string(&response.device_list_updates)?;
Ok(payload)
}
fn update_device_list(
auth_user_id: String,
auth_device_id: String,
auth_access_token: String,
update_payload: String,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let auth_info = AuthInfo {
access_token: auth_access_token,
user_id: auth_user_id,
device_id: auth_device_id,
};
let result = update_device_list_helper(auth_info, update_payload).await;
handle_void_result_as_callback(result, promise_id);
});
}
async fn update_device_list_helper(
auth_info: AuthInfo,
update_payload: String,
) -> Result<(), Error> {
let mut identity_client = get_auth_client(
IDENTITY_SOCKET_ADDR,
auth_info.user_id,
auth_info.device_id,
auth_info.access_token,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let update_request = UpdateDeviceListRequest {
new_device_list: update_payload,
};
identity_client
.update_device_list_for_user(update_request)
.await?;
Ok(())
}
fn upload_secondary_device_keys_and_log_in(
user_id: String,
challenge_response: String,
key_payload: String,
key_payload_signature: String,
content_prekey: String,
content_prekey_signature: String,
notif_prekey: String,
notif_prekey_signature: String,
content_one_time_keys: Vec,
notif_one_time_keys: Vec,
promise_id: u32,
) {
RUNTIME.spawn(async move {
let device_key_upload = DeviceKeyUpload {
device_key_info: Some(IdentityKeyInfo {
payload: key_payload,
payload_signature: key_payload_signature,
social_proof: None,
}),
content_upload: Some(Prekey {
prekey: content_prekey,
prekey_signature: content_prekey_signature,
}),
notif_upload: Some(Prekey {
prekey: notif_prekey,
prekey_signature: notif_prekey_signature,
}),
one_time_content_prekeys: content_one_time_keys,
one_time_notif_prekeys: notif_one_time_keys,
device_type: DEVICE_TYPE.into(),
};
let result = upload_secondary_device_keys_and_log_in_helper(
user_id,
challenge_response,
device_key_upload,
)
.await;
handle_string_result_as_callback(result, promise_id);
});
}
async fn upload_secondary_device_keys_and_log_in_helper(
user_id: String,
challenge_response: String,
device_key_upload: DeviceKeyUpload,
) -> Result {
let mut identity_client = get_unauthenticated_client(
IDENTITY_SOCKET_ADDR,
CODE_VERSION,
DEVICE_TYPE.as_str_name().to_lowercase(),
)
.await?;
let request = SecondaryDeviceKeysUploadRequest {
user_id,
challenge_response,
device_key_upload: Some(device_key_upload),
};
let response = identity_client
.upload_keys_for_registered_device_and_log_in(request)
.await?
.into_inner();
let user_id_and_access_token = UserIDAndDeviceAccessToken::from(response);
Ok(serde_json::to_string(&user_id_and_access_token)?)
}
#[derive(
Debug, derive_more::Display, derive_more::From, derive_more::Error,
)]
pub enum Error {
#[display(fmt = "{}", "_0.message()")]
TonicGRPC(Status),
#[display(fmt = "{}", "_0")]
SerdeJson(serde_json::Error),
#[display(fmt = "Missing response data")]
MissingResponseData,
#[display(fmt = "{}", "_0")]
GRPClient(grpc_clients::error::Error),
}
#[cfg(test)]
mod tests {
use super::{BACKUP_SOCKET_ADDR, CODE_VERSION, IDENTITY_SOCKET_ADDR};
#[test]
fn test_code_version_exists() {
assert!(CODE_VERSION > 0);
}
#[test]
fn test_identity_socket_addr_exists() {
assert!(IDENTITY_SOCKET_ADDR.len() > 0);
assert!(BACKUP_SOCKET_ADDR.len() > 0);
}
}
diff --git a/native/schema/CommRustModuleSchema.js b/native/schema/CommRustModuleSchema.js
index ab22c6e7e..4a9ff50b1 100644
--- a/native/schema/CommRustModuleSchema.js
+++ b/native/schema/CommRustModuleSchema.js
@@ -1,125 +1,126 @@
// @flow
'use strict';
import { TurboModuleRegistry } from 'react-native';
import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport.js';
export interface Spec extends TurboModule {
+generateNonce: () => Promise;
+registerPasswordUser: (
username: string,
password: string,
keyPayload: string,
keyPayloadSignature: string,
contentPrekey: string,
contentPrekeySignature: string,
notifPrekey: string,
notifPrekeySignature: string,
contentOneTimeKeys: $ReadOnlyArray,
notifOneTimeKeys: $ReadOnlyArray,
) => Promise;
+logInPasswordUser: (
username: string,
password: string,
keyPayload: string,
keyPayloadSignature: string,
contentPrekey: string,
contentPrekeySignature: string,
notifPrekey: string,
notifPrekeySignature: string,
contentOneTimeKeys: $ReadOnlyArray,
notifOneTimeKeys: $ReadOnlyArray,
) => Promise;
+registerWalletUser: (
siweMessage: string,
siweSignature: string,
keyPayload: string,
keyPayloadSignature: string,
contentPrekey: string,
contentPrekeySignature: string,
notifPrekey: string,
notifPrekeySignature: string,
contentOneTimeKeys: $ReadOnlyArray,
notifOneTimeKeys: $ReadOnlyArray,
) => Promise;
+logInWalletUser: (
siweMessage: string,
siweSignature: string,
keyPayload: string,
keyPayloadSignature: string,
contentPrekey: string,
contentPrekeySignature: string,
notifPrekey: string,
notifPrekeySignature: string,
contentOneTimeKeys: $ReadOnlyArray,
notifOneTimeKeys: $ReadOnlyArray,
) => Promise;
+updatePassword: (
userID: string,
deviceID: string,
accessToken: string,
password: string,
) => Promise;
+deleteUser: (
userID: string,
deviceID: string,
accessToken: string,
) => Promise;
+getOutboundKeysForUser: (
authUserID: string,
authDeviceID: string,
authAccessToken: string,
userID: string,
) => Promise;
+getInboundKeysForUser: (
authUserID: string,
authDeviceID: string,
authAccessToken: string,
userID: string,
) => Promise;
+versionSupported: () => Promise;
+uploadOneTimeKeys: (
authUserID: string,
authDeviceID: string,
authAccessToken: string,
contentOneTimePreKeys: $ReadOnlyArray,
notifOneTimePreKeys: $ReadOnlyArray,
) => Promise;
+getKeyserverKeys: (
authUserID: string,
authDeviceID: string,
authAccessToken: string,
keyserverID: string,
) => Promise;
+getDeviceListForUser: (
authUserID: string,
authDeviceID: string,
authAccessToken: string,
userID: string,
sinceTimestamp: ?number,
) => Promise;
+updateDeviceList: (
authUserID: string,
authDeviceID: string,
authAccessToken: string,
updatePayload: string,
) => Promise;
+uploadSecondaryDeviceKeysAndLogIn: (
userID: string,
challengeResponse: string,
keyPayload: string,
keyPayloadSignature: string,
contentPrekey: string,
contentPrekeySignature: string,
notifPrekey: string,
notifPrekeySignature: string,
contentOneTimeKeys: $ReadOnlyArray,
notifOneTimeKeys: $ReadOnlyArray,
) => Promise;
+findUserIDForWalletAddress: (walletAddress: string) => Promise;
+ +findUserIDForUsername: (username: string) => Promise;
}
export default (TurboModuleRegistry.getEnforcing(
'CommRustTurboModule',
): Spec);