Skip to content

Commit

Permalink
feat: added possibility to hide or change message after redirect (pul…
Browse files Browse the repository at this point in the history
…l request #66 from BetterBOy)

Added possibility to hide or change message after redirect
  • Loading branch information
rbellens authored Dec 29, 2022
2 parents d136c8f + aa1c766 commit aafaab8
Showing 1 changed file with 59 additions and 40 deletions.
99 changes: 59 additions & 40 deletions lib/openid_client_io.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
library openid_client.io;

import 'openid_client.dart';
import 'dart:async';
import 'dart:io';
import 'dart:developer';

import 'openid_client.dart';

export 'openid_client.dart';

Expand All @@ -13,28 +15,46 @@ class Authenticator {

final int port;

final String? htmlPage;

/// Not working if html is not null
final String? redirectMessage;

Authenticator.fromFlow(
this.flow, {
Function(String url)? urlLancher,
}) : port = flow.redirectUri.port,
String? redirectMessage,
this.htmlPage,
}) : assert(
htmlPage != null ? redirectMessage == null : true,
'You can only use one variable htmlPage (give entire html) or redirectMessage (only string message)',
),
redirectMessage = redirectMessage ?? 'You can now close this window',
port = flow.redirectUri.port,
urlLancher = urlLancher ?? _runBrowser;

Authenticator(Client client,
{this.port = 3000,
this.urlLancher = _runBrowser,
Iterable<String> scopes = const [],
Uri? redirectUri})
: flow = redirectUri == null
? Flow.authorizationCodeWithPKCE(client)
: Flow.authorizationCode(client)
Authenticator(
Client client, {
this.port = 3000,
this.urlLancher = _runBrowser,
Iterable<String> scopes = const [],
Uri? redirectUri,
String? redirectMessage,
this.htmlPage,
}) : assert(
htmlPage != null ? redirectMessage == null : true,
'You can only use one variable htmlPage (give entire html) or redirectMessage (only string message)',
),
redirectMessage = redirectMessage ?? 'You can now close this window',
flow = redirectUri == null ? Flow.authorizationCodeWithPKCE(client) : Flow.authorizationCode(client)
..scopes.addAll(scopes)
..redirectUri = redirectUri ?? Uri.parse('http://localhost:$port/');

Future<Credential> authorize() async {
var state = flow.authenticationUri.queryParameters['state']!;

_requestsByState[state] = Completer();
await _startServer(port);
await _startServer(port, htmlPage, redirectMessage);
urlLancher(flow.authenticationUri.toString());

var response = await _requestsByState[state]!.future;
Expand All @@ -46,36 +66,36 @@ class Authenticator {
Future<void> cancel() async {
final state = flow.authenticationUri.queryParameters['state'];
_requestsByState[state!]?.completeError(Exception('Flow was cancelled'));
final server = await _requestServers.remove(port)!;
await server.close();
final server = await _requestServers.remove(port);
await server?.close();
}

static final Map<int, Future<HttpServer>> _requestServers = {};
static final Map<String, Completer<Map<String, String>>> _requestsByState =
{};

static Future<HttpServer> _startServer(int port) {
return _requestServers[port] ??=
(HttpServer.bind(InternetAddress.anyIPv4, port)
..then((requestServer) async {
print('server started $port');
await for (var request in requestServer) {
print('request $request');
request.response.statusCode = 200;
request.response.headers.set('Content-type', 'text/html');
request.response.writeln('<html>'
'<h1>You can now close this window</h1>'
'<script>window.close();</script>'
'</html>');
await request.response.close();
var result = request.requestedUri.queryParameters;

if (!result.containsKey('state')) continue;
await processResult(result);
}

await _requestServers.remove(port);
}));
static final Map<String, Completer<Map<String, String>>> _requestsByState = {};

static Future<HttpServer> _startServer(int port, String? htmlPage, String? redirectMessage) {
return _requestServers[port] ??= (HttpServer.bind(InternetAddress.anyIPv4, port)
..then((requestServer) async {
log('Server started at port $port');
await for (var request in requestServer) {
request.response.statusCode = 200;
if (redirectMessage != null) {
request.response.headers.contentType = ContentType.html;
request.response.writeln(htmlPage ??
'<html>'
'<h1>$redirectMessage</h1>'
'<script>window.close();</script>'
'</html>');
}
await request.response.close();
var result = request.requestedUri.queryParameters;

if (!result.containsKey('state')) continue;
await processResult(result);
}

await _requestServers.remove(port);
}));
}

/// Process the Result from a auth Request
Expand Down Expand Up @@ -104,8 +124,7 @@ void _runBrowser(String url) {
Process.run('explorer', [url]);
break;
default:
throw UnsupportedError(
'Unsupported platform: ${Platform.operatingSystem}');
throw UnsupportedError('Unsupported platform: ${Platform.operatingSystem}');
}
}

Expand Down

0 comments on commit aafaab8

Please sign in to comment.