SchoolUtils/WebUntis

Use in React Native

xRealNeon opened this issue · 44 comments

Hello I wanted to use this library with React Native but this is not possible because React Native has no standard node modules what can I do?

I’d assume you can just install the required modules via your package manager and React Native bundles them. Is the project where you want to integrate this Library Open Source? If so, could you provide a link?

No not yet open source, the documentation says that the standard node modules are not included and in this case the "url" module

Does this module help? Seems like kind of a poly fill. https://www.npmjs.com/package/url

That worked but now is crypto missing and that don't work with npm i crypto

Hmm okay. I’ll take a look at that later today.

First of all, I would not suggest using this direct in the browser because of CORS. Never checked it, but I think they probably have CORS enabled. You can work around this with a cors proxy. However, I never thought anybody would use this library with this kind of use case. I would need to add support for some kind of cors proxy.

Secondly, you should look into shimming and whether your bundle tool supports it or not. Only the secret login requires crypto. If you don't need to use secret login you can simply replace crypto with an empty module. But don't pin me down on this, I am not sure if only secret login requires crypto.

React Native isn't in the browser it is for mobile apps

React Native isn't in the browser it is for mobile apps

My bad. Read the title to fast. Just thought about react not react native.

Not sure if this project is still working: https://github.com/tradle/rn-nodeify

I tried it but I haven't figured it out

I get this error:

While trying to resolve module `webuntis` from file `/media/jan/Files/Coden/Expo/test/screens/HomeScreen.tsx`, the package `/media/jan/Files/Coden/Expo/test/node_modules/webuntis/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`/media/jan/Files/Coden/Expo/test/node_modules/webuntis/index.js`. Indeed, none of these files exist:

I thought @dunklesToast investigates in this.

Because this is more related to rn, I would suggest asking somewhere specific to rn? For example: https://www.reddit.com/r/reactnative/ If I have time at the weekend I can try look into this again.

One quick solution coming to my mind is using browserify to create a bundle of the module. Maybe this is a bit dirty, but you could give it a try.

Sorry, somehow forgot to answer... It did work for me with rn-nodeify. Did you install all shims or just the crypto shim?

all

I just shimmed crypto and iirc process. Could you try that?

iirc process?

Where did you imported you the shim.js?

Now it is complaining that stream isn't there but I used this command rn-nodeify --install crypto,process,stream,url --hack

I tried to make the package a bit more rn friendly. Now it should only require nodejs internal modules if needed. If you are in a rn context and still need the features (like secret or qr login) you can provide custom implementation. For this, you should look into the otplib package docs (https://github.com/yeojz/otplib). Then you can provide your own configured authenticator instance in rn if needed.

Example (Not tested):

const WebUntisLib = require('webuntis');
const {URL} = require('whatwg-url');
// I am not sure if this works with commonjs modules
const {createDigest, createRandomBytes} = require('@otplib/plugin-crypto-js');
const {Authenticator} = require('@otplib/core');
const {keyDecoder, keyEncoder} = require('@otplib/plugin-thirty-two');

const QRCodeData =
	'untis://setschool?url=[...]&school=[...]&user=[...]&key=[...]&schoolNumber=[...]';

const authenticator = new Authenticator({
  createDigest,
  createRandomBytes,
  keyDecoder,
  keyEncoder
});

const untis = new WebUntisLib.WebUntisQR(QRCodeData, "custom identity", authenticator, URL);

Got this error Unable to resolve "@otplib/plugin-crypto-js"

I did npm i otplib

otplib doesn't install it automatically for you. You still need to install @otplib/plugin-crypto-js.

The package at "node_modules/webuntis/index.js" attempted to import the Node standard library module "url".

The package at "node_modules/webuntis/index.js" attempted to import the Node standard library module "url".

const {URL} = require('whatwg-url');

const untis = new WebUntisLib.WebUntisQR(QRCodeData, "custom identity", authenticator, URL); // <- provide own url module

Of course, you also need to install whatwg-url then.

I have installed whatwg-url

Show me exactly what you wrote.

This with my qr code url

const WebUntisLib = require('webuntis');
const {URL} = require('whatwg-url');
// I am not sure if this works with commonjs modules
const {createDigest, createRandomBytes} = require('@otplib/plugin-crypto-js');
const {Authenticator} = require('@otplib/core');
const {keyDecoder, keyEncoder} = require('@otplib/plugin-thirty-two');

const QRCodeData =
	'untis://setschool?url=[...]&school=[...]&user=[...]&key=[...]&schoolNumber=[...]';

const authenticator = new Authenticator({
  createDigest,
  createRandomBytes,
  keyDecoder,
  keyEncoder
});

const untis = new WebUntisLib.WebUntisQR(QRCodeData, "custom identity", authenticator, URL);

I found some more issues. Will prepare an update.

import { URL } from 'react-native-url-polyfill'; // instead of const {URL} = require('whatwg-url');

And install the newest webuntis update.

The package at "node_modules/webuntis/index.js" attempted to import the Node standard library module "url".

npm i webuntis@^1.13.2 react-native-url-polyfill

And run without cache/clear cache.

Still same error

I don't know on what project you are working. But could you please upload it? Or at least send me? I tried the module on a fresh rn project and it just worked. Even login.

Can you send me the source of your rn project?

I'm using expo by the way

Success with my project?

Haven't tried it because mine is an expo project and yours a React Native CLI project

Can you make it work with an Expo React Native project?

Screen Shot 2020-10-13 at 11 33 04

yarn add buffer react-native-url-polyfill @otplib/plugin-crypto-js 
import React from 'react';
import { useState, useEffect } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import WebUntisLib from 'webuntis';
import { URL } from 'react-native-url-polyfill';
import { createDigest, createRandomBytes } from '@otplib/plugin-crypto-js';
import { Authenticator } from '@otplib/core';
import { keyDecoder, keyEncoder } from '@otplib/plugin-thirty-two';

global.Buffer = require('buffer').Buffer;

const authenticator = new Authenticator({
  createDigest,
  createRandomBytes,
  keyDecoder,
  keyEncoder
});

const QRCodeData =
  '';
  
const untis = new WebUntisLib.WebUntisQR(QRCodeData, "custom identity", authenticator, URL);

export default function App() {
  const [ready, setReady] = useState("No");
  const [error, setError] = useState("");

  untis.login().then(() => {
    setReady("Yes");
  }).catch(e => {
    setError(e.message);
  });

  return (
    <View style={styles.container}>
      <Text>Ready: {ready}</Text>
      <Text>Error: {error}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Works thanks that helped a lot