Skip to content

Commit

Permalink
Improve webview approach and introduce Linows class
Browse files Browse the repository at this point in the history
  • Loading branch information
ThexXTURBOXx committed Feb 7, 2024
1 parent 25cfa23 commit 31e9074
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 33 deletions.
22 changes: 6 additions & 16 deletions flutter_web_auth_2/example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'dart:async';
import 'dart:io' show HttpServer, Platform;
import 'dart:io' show HttpServer;

import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:flutter/foundation.dart';
Expand Down Expand Up @@ -99,17 +99,11 @@ class MyAppState extends State<MyApp> {

req.response.headers.add('Content-Type', 'text/html');

// Windows needs some callback URL on localhost
req.response.write(
(Platform.isLinux)
? html.replaceFirst(
'CALLBACK_URL_HERE',
'http://localhost:43824/success?code=1337',
)
: html.replaceFirst(
'CALLBACK_URL_HERE',
'foobar://success?code=1337',
),
html.replaceFirst(
'CALLBACK_URL_HERE',
'foobar://success?code=1337',
),
);

await req.response.close();
Expand All @@ -126,14 +120,10 @@ class MyAppState extends State<MyApp> {
// the socket server...
final url = kIsWeb ? '${Uri.base}auth.html' : 'http://127.0.0.1:43823/';

// Windows needs some callback URL on localhost
final callbackUrlScheme =
!kIsWeb && (Platform.isLinux) ? 'http://localhost:43824' : 'foobar';

try {
final result = await FlutterWebAuth2.authenticate(
url: url,
callbackUrlScheme: callbackUrlScheme,
callbackUrlScheme: 'foobar',
options: const FlutterWebAuth2Options(
timeout: 5, // example: 5 seconds timeout
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@

#include "generated_plugin_registrant.h"

#include <desktop_webview_window/desktop_webview_window_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
#include <window_to_front/window_to_front_plugin.h>

void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) desktop_webview_window_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopWebviewWindowPlugin");
desktop_webview_window_plugin_register_with_registrar(desktop_webview_window_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
desktop_webview_window
url_launcher_linux
window_to_front
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
import FlutterMacOS
import Foundation

import desktop_webview_window
import flutter_web_auth_2
import path_provider_foundation
import url_launcher_macos
import window_to_front

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin"))
FlutterWebAuth2Plugin.register(with: registry.registrar(forPlugin: "FlutterWebAuth2Plugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WindowToFrontPlugin.register(with: registry.registrar(forPlugin: "WindowToFrontPlugin"))
}
7 changes: 6 additions & 1 deletion flutter_web_auth_2/example/windows/flutter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
# https://github.com/flutter/flutter/issues/57146.
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")

# Set fallback configurations for older versions of the flutter tool.
if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
set(FLUTTER_TARGET_PLATFORM "windows-x64")
endif()

# === Flutter Library ===
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")

Expand Down Expand Up @@ -92,7 +97,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
windows-x64 $<CONFIG>
${FLUTTER_TARGET_PLATFORM} $<CONFIG>
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

#include "generated_plugin_registrant.h"

#include <desktop_webview_window/desktop_webview_window_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
#include <window_to_front/window_to_front_plugin.h>

void RegisterPlugins(flutter::PluginRegistry* registry) {
DesktopWebviewWindowPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DesktopWebviewWindowPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
WindowToFrontPluginRegisterWithRegistrar(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
desktop_webview_window
url_launcher_windows
window_to_front
)
Expand Down
3 changes: 1 addition & 2 deletions flutter_web_auth_2/lib/flutter_web_auth_2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import 'package:flutter_web_auth_2_platform_interface/flutter_web_auth_2_platfor

export 'src/options.dart';
export 'src/unsupported.dart'
if (dart.library.io) 'src/server.dart'
if (dart.library.io) 'src/linows.dart'
if (dart.library.html) 'src/web.dart';
export 'src/windows.dart';

class _OnAppLifecycleResumeObserver extends WidgetsBindingObserver {
final Function onResumed;
Expand Down
44 changes: 44 additions & 0 deletions flutter_web_auth_2/lib/src/linows.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'dart:async';

import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
import 'package:flutter_web_auth_2/src/server.dart';
import 'package:flutter_web_auth_2/src/webview.dart';
import 'package:flutter_web_auth_2_platform_interface/flutter_web_auth_2_platform_interface.dart';

/// Implements the plugin interface for Linux and Windows (Linows)
class FlutterWebAuth2LinowsPlugin extends FlutterWebAuth2Platform {
final FlutterWebAuth2Platform _webviewImpl = FlutterWebAuth2WebViewPlugin();
final FlutterWebAuth2Platform _serverImpl = FlutterWebAuth2ServerPlugin();

/// Registers the Linows super-implementation.
static void registerWith() {
FlutterWebAuth2Platform.instance = FlutterWebAuth2LinowsPlugin();
}

@override
Future<String> authenticate({
required String url,
required String callbackUrlScheme,
required Map<String, dynamic> options,
}) async {
final parsedOptions = FlutterWebAuth2Options.fromJson(options);
if (parsedOptions.useWebview) {
return _webviewImpl.authenticate(
url: url,
callbackUrlScheme: callbackUrlScheme,
options: options,
);
}
return _serverImpl.authenticate(
url: url,
callbackUrlScheme: callbackUrlScheme,
options: options,
);
}

@override
Future clearAllDanglingCalls() async {
await _serverImpl.clearAllDanglingCalls();
await _webviewImpl.clearAllDanglingCalls();
}
}
14 changes: 13 additions & 1 deletion flutter_web_auth_2/lib/src/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ class FlutterWebAuth2Options {
/// MALICIOUS ATTACKERS!
final bool silentAuth;

/// **Only has an effect on Linux and Windows!**
/// When set to `true`, use the new Webview implementation.
/// When set to `false`, the old approach using an internal server is being
/// used in order to fetch the HTTP result. When using the internal server,
/// please keep in mind that you cannot choose any callback URL scheme, as
/// described in https://github.com/ThexXTURBOXx/flutter_web_auth_2/issues/25
final bool useWebview;

const FlutterWebAuth2Options({
bool? preferEphemeral,
this.debugOrigin,
Expand All @@ -104,11 +112,13 @@ class FlutterWebAuth2Options {
int? timeout,
String? landingPageHtml,
bool? silentAuth,
bool? useWebview,
}) : preferEphemeral = preferEphemeral ?? false,
intentFlags = intentFlags ?? defaultIntentFlags,
timeout = timeout ?? 5 * 60,
landingPageHtml = landingPageHtml ?? _defaultLandingPage,
silentAuth = silentAuth ?? false;
silentAuth = silentAuth ?? false,
useWebview = useWebview ?? true;

FlutterWebAuth2Options.fromJson(Map<String, dynamic> json)
: this(
Expand All @@ -119,6 +129,7 @@ class FlutterWebAuth2Options {
timeout: json['timeout'],
landingPageHtml: json['landingPageHtml'],
silentAuth: json['silentAuth'],
useWebview: json['useWebview'],
);

Map<String, dynamic> toJson() => {
Expand All @@ -129,5 +140,6 @@ class FlutterWebAuth2Options {
'timeout': timeout,
'landingPageHtml': landingPageHtml,
'silentAuth': silentAuth,
'useWebview': useWebview,
};
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import 'dart:async';

import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_web_auth_2_platform_interface/flutter_web_auth_2_platform_interface.dart';
import 'package:path_provider/path_provider.dart';

class FlutterWebAuth2WindowsPlugin extends FlutterWebAuth2Platform {
/// Implements the plugin interface using the Webview interface (currently used
/// by Windows and Linux).
class FlutterWebAuth2WebViewPlugin extends FlutterWebAuth2Platform {
bool authenticated = false;
Webview? webview;

/// Registers the Webview implementation.
static void registerWith() {
FlutterWebAuth2Platform.instance = FlutterWebAuth2WindowsPlugin();
FlutterWebAuth2Platform.instance = FlutterWebAuth2WebViewPlugin();
}

@override
Expand All @@ -21,17 +23,14 @@ class FlutterWebAuth2WindowsPlugin extends FlutterWebAuth2Platform {
required Map<String, dynamic> options,
}) async {
if (!await WebviewWindow.isWebviewAvailable()) {
//Microsofts WebView2 must be installed for this to work
// Microsoft's WebView2 must be installed for this to work
throw StateError('Webview is not available');
}
//Reset
authenticated = false;
webview?.close();

final c = Completer<String>();
debugPrint(
'''Launching webview with url: $url, callbackUrlScheme: $callbackUrlScheme, tmpDir: ${(await getTemporaryDirectory()).path}''',
);
webview = await WebviewWindow.create(
configuration: CreateConfiguration(
windowHeight: 720,
Expand All @@ -47,7 +46,7 @@ class FlutterWebAuth2WindowsPlugin extends FlutterWebAuth2Platform {
authenticated = true;
webview?.close();
/**
* Not setting the webview to null will cause a crash if the
* Not setting the webview to null will cause a crash if the
* application tries to open another webview
*/
webview = null;
Expand All @@ -58,7 +57,7 @@ class FlutterWebAuth2WindowsPlugin extends FlutterWebAuth2Platform {
webview!.onClose.whenComplete(
() {
/**
* Not setting the webview to null will cause a crash if the
* Not setting the webview to null will cause a crash if the
* application tries to open another webview
*/
webview = null;
Expand Down
8 changes: 4 additions & 4 deletions flutter_web_auth_2/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ flutter:
ios:
pluginClass: FlutterWebAuth2Plugin
linux:
dartPluginClass: FlutterWebAuth2ServerPlugin
fileName: src/server.dart
dartPluginClass: FlutterWebAuth2LinowsPlugin
fileName: src/linows.dart
macos:
pluginClass: FlutterWebAuth2Plugin
web:
pluginClass: FlutterWebAuth2WebPlugin
fileName: src/web.dart
windows:
dartPluginClass: FlutterWebAuth2WindowsPlugin
fileName: src/windows.dart
dartPluginClass: FlutterWebAuth2LinowsPlugin
fileName: src/linows.dart

0 comments on commit 31e9074

Please sign in to comment.