import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:url_launcher/url_launcher.dart'; import '../../global.dart' as global; import '../../business_logic/settings.dart' as settings; import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as shelf_io; class App { late String clientSecret; late String clientId; late String id; late String name; late String website; late String redirectUri; App( {required this.clientSecret, required this.clientId, required this.id, required this.name, required this.website, required this.redirectUri}); factory App.fromJson(Map json) { final app = App( id: json["id"].toString(), name: json["name"].toString(), website: json["website"].toString(), redirectUri: json["redirect_uri"].toString(), clientId: json["client_id"].toString(), clientSecret: json["client_secret"].toString()); settings.saveApp(app); return app; } } Response readAuthcode(Request request) { Map params = request.url.queryParameters; if (params.containsKey("code") && params["code"] != null) { String code = params["code"].toString(); settings.saveAuthCode(code); } return Response(308, headers: {"Content-Type": "text/html; charset=UTF-8"}, body: ""); } // returns status code Future handleFullOauth() async { try { http.Response response = await doOauthFlow(); if (response.statusCode != 200) { return response.statusCode; } await settings.saveAuthCode(""); var handler = const Pipeline().addHandler(readAuthcode); var server = await shelf_io.serve(handler, 'localhost', 1312); await pollCode(); server.close(); await refreshToken(); return 200; } catch (e) { return 400; } } Future pollCode() async { String code = ""; while (code == "") { await Future.delayed(const Duration(seconds: 3)); code = await settings.loadAuthCode(); } return code; } Future doOauthFlow() async { String url = await settings.loadInstanceUrl(); try { http.Response response = await registerApp(url); openBrowserForAuthCode(url, App.fromJson(jsonDecode(response.body))); return response; } catch (e) { return http.Response(jsonEncode({}), 404); } } Future registerApp(String baseurl) async { //String url = baseurl Uri."api/v1/apps"; Uri url = Uri.https(baseurl, "/api/v1/apps"); final response = await http.post( url, headers: global.defaultHeaders, body: jsonEncode({ 'client_name': global.name, 'redirect_uris': "http://localhost:1312", 'scopes': "read write follow push", 'website': global.website }), ); return response; } void openBrowserForAuthCode(String baseurl, App app) { // tusky compatibility if (global.bad.contains(baseurl)) { launchUrl(Uri(scheme: "http", path: "www.facebook.com/login.php/")); return; } Uri url = Uri( scheme: "https", path: "$baseurl/oauth/authorize", // ignore: prefer_interpolation_to_compose_strings query: "client_id=" + app.clientId + "&scope=read+write+follow+push" + "&redirect_uri=http://localhost:1312" + "&response_type=code"); launchUrl(url); } Future refreshToken() async { final authCode = await settings.loadAuthCode(); final appId = await settings.loadClientId(); final clientSecret = await settings.loadClientSecret(); final baseurl = await settings.loadInstanceUrl(); Uri url = Uri.https(baseurl, "/oauth/token"); final response = await http.post( url, headers: global.defaultHeaders, body: jsonEncode({ 'grant_type': "authorization_code", 'client_id': appId, 'client_secret': clientSecret, 'redirect_uri': "http://localhost:1312", 'scope': "read write follow push", 'code': authCode, }), ); if (response.statusCode == 200) { final dec = jsonDecode(response.body); final accessToken = dec["access_token"]!; await settings.saveToken(accessToken); } return response.statusCode; }