Skip to content

Commit

Permalink
Merge pull request #77 from humhub/55-test-unreachable-humhub
Browse files Browse the repository at this point in the history
Fix Unreachable HumHub
  • Loading branch information
luke- authored Jun 12, 2023
2 parents 5e25c19 + 8a92513 commit 8224ba3
Show file tree
Hide file tree
Showing 8 changed files with 319 additions and 96 deletions.
7 changes: 2 additions & 5 deletions lib/models/manifest.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@ class Manifest {
this.backgroundColor, this.themeColor);

String get baseUrl {
int index = startUrl.indexOf("humhub.com");
if (index != -1) {
return startUrl.substring(0, index + "humhub.com".length);
}
throw Exception("Can't define base url");
Uri url = Uri.parse(startUrl);
return url.origin;
}

factory Manifest.fromJson(Map<String, dynamic> json) {
Expand Down
84 changes: 14 additions & 70 deletions lib/pages/opener.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:humhub/models/hum_hub.dart';
import 'package:humhub/pages/web_view.dart';
import 'package:humhub/util/api_provider.dart';
import 'package:humhub/util/const.dart';
import 'package:humhub/util/form_helper.dart';
import 'package:humhub/models/manifest.dart';
import 'package:humhub/util/opener_controller.dart';
import 'package:humhub/util/providers.dart';
import 'package:loggy/loggy.dart';
import 'package:rive/rive.dart';
import 'help/help.dart';

Expand All @@ -21,11 +16,7 @@ class Opener extends ConsumerStatefulWidget {
}

class OpenerState extends ConsumerState<Opener> {
final helper = FormHelper();
final String formUrlKey = "redirect_url";
final String error404 = "404";
late String? postcodeErrorMessage;
TextEditingController urlTextController = TextEditingController();
late OpenerController controlLer;
late RiveAnimationController _controller;
late SimpleAnimation _animation;
// Fade out Logo and opener when redirecting
Expand All @@ -40,6 +31,7 @@ class OpenerState extends ConsumerState<Opener> {

@override
Widget build(BuildContext context) {
controlLer = OpenerController(ref: ref);
InputDecoration openerDecoration = InputDecoration(
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(
Expand All @@ -62,7 +54,7 @@ class OpenerState extends ConsumerState<Opener> {
body: SafeArea(
bottom: false,
child: Form(
key: helper.key,
key: controlLer.helper.key,
child: Stack(
fit: StackFit.expand,
children: [
Expand Down Expand Up @@ -99,16 +91,16 @@ class OpenerState extends ConsumerState<Opener> {
future: ref.read(humHubProvider).getLastUrl(),
builder: (context, snapshot) {
if (snapshot.hasData) {
urlTextController.text = snapshot.data!;
controlLer.urlTextController.text = snapshot.data!;
return TextFormField(
controller: urlTextController,
controller: controlLer.urlTextController,
cursorColor: Theme.of(context).textTheme.bodySmall?.color,
onSaved: helper.onSaved(formUrlKey),
onSaved: controlLer.helper.onSaved(controlLer.formUrlKey),
style: const TextStyle(
decoration: TextDecoration.none,
),
decoration: openerDecoration,
validator: validateUrl,
validator: controlLer.validateUrl,
);
}
return progress;
Expand All @@ -134,7 +126,12 @@ class OpenerState extends ConsumerState<Opener> {
width: 140,
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(5)),
child: TextButton(
onPressed: onPressed,
onPressed: () async {
await controlLer.initHumHub();
ref.read(humHubProvider).getInstance().then((value) {
Navigator.pushNamed(ref.context, WebViewApp.path, arguments: value.manifest);
});
},
child: Text(
'Connect',
style: TextStyle(color: openerColor, fontSize: 20),
Expand Down Expand Up @@ -196,57 +193,4 @@ class OpenerState extends ConsumerState<Opener> {
),
);
}

onPressed() async {
// Validate the URL format and if !value.isEmpty
if (!helper.validate()) return;
helper.save();
// Get the manifest.json for given url.
Uri url = assumeUrl(helper.model[formUrlKey]!);
logInfo("Host: ${url.host}");
AsyncValue<Manifest>? asyncData;
for (var i = url.pathSegments.length - 1; i >= 0; i--) {
String urlIn = "${url.origin}/${url.pathSegments.getRange(0, i).join('/')}";
asyncData = await APIProvider.of(ref).request(Manifest.get(i != 0 ? urlIn : url.origin));
if (!asyncData.hasError) break;
}
if (url.pathSegments.isEmpty) {
asyncData = await APIProvider.of(ref).request(Manifest.get(url.origin));
}
// If manifest.json does not exist the url is incorrect.
// This is a temp. fix the validator expect sync. function this is some established workaround.
// In the future we could define our own TextFormField that would also validate the API responses.
// But it this is not acceptable I can suggest simple popup or tempPopup.
if (asyncData!.hasError) {
log("Open URL error: $asyncData");
String value = urlTextController.text;
urlTextController.text = error404;
helper.validate();
urlTextController.text = value;
} else {
Manifest manifest = asyncData.value!;
// Set the manifestStateProvider with the manifest value so that it's globally accessible
// Generate hash and save it to store
String lastUrl = await ref.read(humHubProvider).getLastUrl();
String currentUrl = urlTextController.text;
String hash = HumHub.generateHash(32);
if (lastUrl == currentUrl) hash = ref.read(humHubProvider).randomHash ?? hash;
ref.read(humHubProvider).setInstance(HumHub(manifest: manifest, randomHash: hash));
if (context.mounted) Navigator.pushNamed(context, WebViewApp.path, arguments: manifest);
}
}

Uri assumeUrl(String url) {
if (url.startsWith("https://") || url.startsWith("http://")) return Uri.parse(url);
return Uri.parse("https://$url");
}

String? validateUrl(String? value) {
if (value == error404) return 'Your HumHub installation does not exist';

if (value == null || value.isEmpty) {
return 'Specify you HumHub location';
}
return null;
}
}
6 changes: 4 additions & 2 deletions lib/pages/web_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
);
}

Future<NavigationActionPolicy?> _shouldOverrideUrlLoading(InAppWebViewController controller, NavigationAction action) async {
Future<NavigationActionPolicy?> _shouldOverrideUrlLoading(
InAppWebViewController controller, NavigationAction action) async {
// 1st check if url is not def. app url and open it in a browser or inApp.
final url = action.request.url!.origin;
if (!url.startsWith(manifest.baseUrl)) {
Expand Down Expand Up @@ -171,7 +172,8 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
if (url!.path.contains('/user/auth/login')) {
webViewController.evaluateJavascript(source: "document.querySelector('#login-rememberme').checked=true");
webViewController.evaluateJavascript(
source: "document.querySelector('#account-login-form > div.form-group.field-login-rememberme').style.display='none';");
source:
"document.querySelector('#account-login-form > div.form-group.field-login-rememberme').style.display='none';");
}
_pullToRefreshController?.endRefreshing();
}
Expand Down
88 changes: 88 additions & 0 deletions lib/util/opener_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart';
import 'package:humhub/models/hum_hub.dart';
import 'package:humhub/models/manifest.dart';
import 'package:humhub/util/providers.dart';
import 'package:http/http.dart' as http;
import 'api_provider.dart';
import 'form_helper.dart';
import 'dart:developer';

class OpenerController {
late AsyncValue<Manifest>? asyncData;
bool doesViewExist = false;
final helper = FormHelper();
TextEditingController urlTextController = TextEditingController();
late String? postcodeErrorMessage;
final String formUrlKey = "redirect_url";
final String error404 = "404";
final WidgetRef ref;

OpenerController({required this.ref});

findManifest(String url) async {
Uri uri = assumeUrl(url);
for (var i = uri.pathSegments.length - 1; i >= 0; i--) {
String urlIn = "${uri.origin}/${uri.pathSegments.getRange(0, i).join('/')}";
asyncData = await APIProvider.of(ref).request(Manifest.get(i != 0 ? urlIn : uri.origin));
if (!asyncData!.hasError) break;
}
if (uri.pathSegments.isEmpty) {
asyncData = await APIProvider.of(ref).request(Manifest.get(uri.origin));
}
checkHumHubModuleView(uri);
}

checkHumHubModuleView(Uri uri) async {
Response? response;
response = await http.Client().get(uri).catchError((err) {return Response("Found manifest but not humhub.modules.ui.view tag", 404);});

doesViewExist = response.statusCode == 200 && response.body.contains('humhub.modules.ui.view');
}

initHumHub() async {
// Validate the URL format and if !value.isEmpty
if (!helper.validate()) return;
helper.save();
// Get the manifest.json for given url.
await findManifest(helper.model[formUrlKey]!);
// If manifest.json does not exist the url is incorrect.
// This is a temp. fix the validator expect sync. function this is some established workaround.
// In the future we could define our own TextFormField that would also validate the API responses.
// But it this is not acceptable I can suggest simple popup or tempPopup.
if (asyncData!.hasError || doesViewExist) {
log("Open URL error: $asyncData");
String value = urlTextController.text;
urlTextController.text = error404;
helper.validate();
urlTextController.text = value;
} else {
Manifest manifest = asyncData!.value!;
// Set the manifestStateProvider with the manifest value so that it's globally accessible
// Generate hash and save it to store
String lastUrl = "";
lastUrl = await ref.read(humHubProvider).getLastUrl();
String currentUrl = urlTextController.text;
String hash = HumHub.generateHash(32);
if (lastUrl == currentUrl) hash = ref.read(humHubProvider).randomHash ?? hash;
ref.read(humHubProvider).setInstance(HumHub(manifest: manifest, randomHash: hash));
}
}



Uri assumeUrl(String url) {
if (url.startsWith("https://") || url.startsWith("http://")) return Uri.parse(url);
return Uri.parse("https://$url");
}

String? validateUrl(String? value) {
if (value == error404) return 'Your HumHub installation does not exist';

if (value == null || value.isEmpty) {
return 'Specify you HumHub location';
}
return null;
}
}
Loading

0 comments on commit 8224ba3

Please sign in to comment.