-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use userbase in React Native #275
Comments
Oh man, I'm sorry for this rabbit hole you've gone down. That twitter response was me. The most challenging aspects of getting On the crypto issue: to me, this looks like an implementation error with On the websocket polyfill: perhaps I believe in the end, would need polyfills for all of these to make sure everything works. Could help serve as a guide maybe. |
No worries about the rabbit hole 😄 It actually gave me a deeper understanding of how userbase works internally. I think I'll continue to look into it a bit more as I have some time to do so. I will definitely take a closer look at the react-native-webview-crypto implementation, as it seems to be the biggest problem. If I find a solution or encounter any other problems that someone could help me with, I would comment in here again. Maybe it would help someone else for future reference. |
@Fubinator I would definitely be interested in React Native support for Userbase. I'm currently playing around with Userbase in Ionic. I like React Native significantly more than Ionic, so if you need help with this let me know, I'd for sure want to assist when I have the time! |
@jneterer I'll briefly describe my current evaluation of the problem and what we need to make it work:
So what is the current status? I think there are two options: Either we continue to look for bugs in the libraries and try to reproduce them minimally so that we eventually write bug reports, or we find another library that works out of the box. Another problem is that all libraries so far have been very slow. My current polyfill setup looks like this: import './shim.js'; // rn-nodeify shims
const {Crypto} = require('@peculiar/webcrypto');
import localStorage from 'react-native-sync-localstorage';
export default async function initialize(): Promise<void> {
// crypto
global.crypto = new Crypto();
// localStorage
await localStorage.getAllFromLocalStorage();
global.localStorage = localStorage;
// sessionStorage
// https://gist.github.com/juliocesar/926500#gistcomment-1620487
global.sessionStorage = {
_data: {},
setItem: function (id: string, val: any) {
return (this._data[id] = String(val));
},
getItem: function (id: string) {
return Object.prototype.hasOwnProperty.call(this._data, 'id')
? this._data[id]
: undefined;
},
removeItem: function (id: string) {
return delete this._data[id];
},
clear: function () {
return (this._data = {});
},
};
// DOMException
global.DOMException = require('domexception');
} I hope this is a good overview to try out for yourself. |
So after a little bit of further investigation I managed to sign in using the In my opinion, const crypto = require('crypto');
console.log(crypto.createSign('SHA256')); I've created an issue on |
@Fubinator this is really encouraging to hear! How was the speed of signing in? |
@j-berman I do have one question when it comes to mobile apps built with Userbase. If I've set remember me to local storage and the user at some point deletes the app, then they want to sign into the web app but they've forgotten their password, will they be able to since they've deleted the app? Or will they have to reinstall and reset it there? The question comes from this line in the Forgot Password docs "Recovery will not be possible if the user loses access to all previously used devices". Is it the physical device that is important, or the browser/app? |
@jneterer Sign in speed is not good. I stopped the time and it's taking ~28 seconds. BTW: It is possible to change the name of the SHA-256 algorithm in userbase.js directly so that it works. Just change the constant to
Maybe that would be a possibility if everything else doesn't work. |
I've created a repository with a little bit of explanation and the current status: I think this is better than spamming my intermediate steps in here all the time 😄 |
@Fubinator great idea, I'll check your repo out! |
For apps that are end-to-end encrypted, if the user deletes the app and all the app's data, this will likely delete the user's encryption key too which is stored locally when you use the local storage option. If the user loses both their password and the encryption key, the user wouldn't be able to access their encrypted data. |
Any updates? |
I asked on Twitter if there was a way to use userbase in React Native. After some time of playing around, however, I still haven't managed to get userbase working. I am opening this issue to share my experience so far and maybe someone can help me find the solution (This is also too much for Twitter 😄).
The proposed approach was to use
userbase-js-node
with rn-nodeify. In the process, I ran into a few problems, which I'll explain below.So first things first:
I've had massive problems with using
expo
in conjunction withrn-nodeify
(See here). I ended up ditchingexpo
and used thereact-native-cli
for creating the project.After setting up the initial project and installing rn-nodeify, I tried to get userbase-js-node working. The problem here is that with
userbase-js-node
,node-localstorage
is used.node-localstorage
simulates localstorage by creating a file on disk, which is not possible in React Native. You could possibly somehow polyfill withreact-native-fs
, but that also seems a little awkward.@peculiar/webcrypto
doesn't seem to work well in React Native either.I ended up playing around with userbase's JavaScript SDK, which took me the furthest. I was able to polyfill the localstorage with
react-native-sync-localstorage
to the point that userbase stopped complaining.Initialising the app does not throw any errors. I suspect this is because no session exists. However, as soon as I call userbase.signUp I get the following error:
WebCryptoUnavailable: The WebCrypto API is unavailable. Please make sure your website uses https.
According to userbase's source code this error is thrown when
window.crypto.subtle
is not available. When I logged that in my app it was indeed undefined. So I figured I needed a polyfill forwindow.crypto.subtle
and came across react-native-webview-crypto. This does polyfillcrypto.subtle
, but now I get the following error:I am stuck at this point. I think the error comes directly from
window.crypto.subtle
, but I don't find much on google when I search for it directly. Also, I'm not sure if I'm too naive about polyfilling. Replacing everything that is not available with different libraries doesn't seem to be the best approach.If anyone has any further suggestions or possibly even userbase in React Native running, I would be very happy if they could point me in the right direction.
EDIT: According to this a key is not extractable, when there is a boolean flag set to
false
when callingwindow.crypto.subtle.generateKey()
. However, when searching in the repo, I can't find any occurrences where the flag is set to false.EDIT2: After some debugging, it seems like the error occurs here:
userbase/src/userbase-js/src/Crypto/aes-gcm.js
Lines 182 to 188 in 74d09f7
For testing purposes I've set
KEY_IS_EXTRACTABLE
to true. As soon as I set the flag, I can create a user. Now it seems that the websocket is broken, as I get the following error:WebSocket error: Can't find variable: DOMException
EDIT3: The last error was a little bit misleading. It actually occurs here:
userbase/src/userbase-js/src/Crypto/hmac.js
Lines 14 to 26 in 74d09f7
Again, after I set the key to be extractable, the error is gone. I can even log in and get a session. I won't try any further from here, as I don't know what cryptographic complications this presents either. However, maybe someone knows if the problem is with the implementation of
react-native-webview-crypto
.The text was updated successfully, but these errors were encountered: