Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 56 additions & 48 deletions lib/src/api/ck_auth_web_view.dart
Original file line number Diff line number Diff line change
@@ -1,83 +1,91 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

import '../ck_constants.dart';

class CKAuthWebView extends StatefulWidget
{
class CKAuthWebView extends StatefulWidget {
final String title = "iCloud Authentication";

final String authenticationURL;
final String redirectURLPattern;

CKAuthWebView({Key? key, required this.authenticationURL, required this.redirectURLPattern}) : super(key: key);
CKAuthWebView({
Key? key,
required this.authenticationURL,
required this.redirectURLPattern,
}) : super(key: key);

@override
State<StatefulWidget> createState() => _CKAuthWebViewState();
}

class _CKAuthWebViewState extends State<CKAuthWebView>
{
class _CKAuthWebViewState extends State<CKAuthWebView> {
late WebViewController webViewController;

@override
void initState()
{
void initState() {
super.initState();
// Enable hybrid composition, as detailed in https://pub.dev/packages/webview_flutter
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();

webViewController = WebViewController()
..loadRequest(Uri.parse(widget.authenticationURL));

webViewController.setJavaScriptMode(JavaScriptMode.unrestricted);
webViewController.setNavigationDelegate(
NavigationDelegate(
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith(widget.redirectURLPattern)) {
var redirectURI = Uri.dataFromString(request.url);
var ckWebAuthTokenEncoded = redirectURI
.queryParameters[CKConstants.WEB_AUTH_TOKEN_PARAMETER];
if (ckWebAuthTokenEncoded == null) {
Navigator.pop(context, CKAuthCallback(CKAuthState.failure));
} else {
var ckWebAuthToken =
Uri.decodeQueryComponent(ckWebAuthTokenEncoded);
Navigator.pop(
context,
CKAuthCallback(
CKAuthState.success,
authToken: ckWebAuthToken,
));
}
}

return NavigationDecision.navigate;
},
),
);
}

@override
Widget build(BuildContext context)
{
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.pop(context, CKAuthCallback(CKAuthState.cancel)),
onPressed: () =>
Navigator.pop(context, CKAuthCallback(CKAuthState.cancel)),
),
title: Text(widget.title),
),
body: Builder(builder: (BuildContext context) {
return WebView(
initialUrl: widget.authenticationURL,
javascriptMode: JavascriptMode.unrestricted,
navigationDelegate: (NavigationRequest request) {
if (request.url.startsWith(widget.redirectURLPattern))
{
var redirectURI = Uri.dataFromString(request.url);
var ckWebAuthTokenEncoded = redirectURI.queryParameters[CKConstants.WEB_AUTH_TOKEN_PARAMETER];
if (ckWebAuthTokenEncoded == null)
{
Navigator.pop(context, CKAuthCallback(CKAuthState.failure));
}
else
{
var ckWebAuthToken = Uri.decodeQueryComponent(ckWebAuthTokenEncoded);
Navigator.pop(context, CKAuthCallback(CKAuthState.success, authToken: ckWebAuthToken));
}
}

return NavigationDecision.navigate;
},
);
})
body: Builder(
builder: (BuildContext context) {
return WebViewWidget(
controller: webViewController,
);
},
),
);
}
}

enum CKAuthState
{
success,
failure,
cancel
}
enum CKAuthState { success, failure, cancel }

class CKAuthCallback
{
class CKAuthCallback {
final CKAuthState state;
final String? authToken;

CKAuthCallback(CKAuthState state, {String? authToken}) : state = state, authToken = authToken;
}
CKAuthCallback(CKAuthState state, {String? authToken})
: state = state,
authToken = authToken;
}
Loading