diff --git a/lib/business_logic/auth/oauth.dart b/lib/business_logic/auth/oauth.dart index e13995f..8438429 100644 --- a/lib/business_logic/auth/oauth.dart +++ b/lib/business_logic/auth/oauth.dart @@ -22,13 +22,15 @@ class App { required this.website, required this.redirectUri}); factory App.fromJson(Map json) { - return App( + 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; } } @@ -57,6 +59,7 @@ Future handleFullOauth() async { var server = await shelf_io.serve(handler, 'localhost', 1312); await pollCode(); server.close(); + await refreshToken(); return 200; } catch (e) { return 400; @@ -86,14 +89,16 @@ Future doOauthFlow() async { 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", - 'website': global.website - })); + 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; } @@ -109,8 +114,35 @@ void openBrowserForAuthCode(String baseurl, App app) { // ignore: prefer_interpolation_to_compose_strings query: "client_id=" + app.clientId + - "&scope=read+write" + + "&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; +} diff --git a/lib/business_logic/settings.dart b/lib/business_logic/settings.dart index 2f5cde5..71ba9c5 100644 --- a/lib/business_logic/settings.dart +++ b/lib/business_logic/settings.dart @@ -2,6 +2,7 @@ import 'package:flutter/painting.dart'; import 'package:intl/intl.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../global.dart' as global; +import '../business_logic/auth/oauth.dart' as oauth; enum Settings { instanceUrl, @@ -58,3 +59,44 @@ Future loadLocale() async { } return Locale(locale); } + +Future saveApp(oauth.App app) async { + final prefs = await SharedPreferences.getInstance(); + prefs.setString("client-secret", app.clientSecret); + prefs.setString("client-id", app.clientId); +} + +Future loadClientSecret() async { + final prefs = await SharedPreferences.getInstance(); + final secret = prefs.getString("client-secret"); + if (secret == null) { + return ""; + } else { + return secret; + } +} + +Future loadClientId() async { + final prefs = await SharedPreferences.getInstance(); + final id = prefs.getString("client-id"); + if (id == null) { + return ""; + } else { + return id; + } +} + +Future saveToken(String token) async { + final prefs = await SharedPreferences.getInstance(); + return await prefs.setString("access-token", token); +} + +Future loadToken() async { + final prefs = await SharedPreferences.getInstance(); + final id = prefs.getString("access-token"); + if (id == null) { + return ""; + } else { + return id; + } +} diff --git a/lib/business_logic/timeline/timeline.dart b/lib/business_logic/timeline/timeline.dart index a5370fe..f26a27a 100644 --- a/lib/business_logic/timeline/timeline.dart +++ b/lib/business_logic/timeline/timeline.dart @@ -1,7 +1,20 @@ import 'package:http/http.dart' as http; +import '../settings.dart' as settings; +import '../../global.dart' as global; -class Thread {} +Future getTimelineFromServer() async { + final token = await settings.loadToken(); + final baseUrl = await settings.loadInstanceUrl(); + final url = Uri( + scheme: "https", + host: baseUrl, + path: "/api/v1/timelines/home", + ); -class Post {} + Map headers = {"Authorization": "Bearer $token"}; + headers.addAll(global.defaultHeaders); -class Timeline {} + final response = await http.get(url, headers: headers); + + return response; +} diff --git a/lib/global.dart b/lib/global.dart index 6abfd5c..2371ca3 100644 --- a/lib/global.dart +++ b/lib/global.dart @@ -1,7 +1,7 @@ import 'package:flutter/painting.dart'; const String name = "loris"; -const String version = "v0.1 'not even alpha'"; +const String version = "v0.1 'is this thing on'"; const String useragent = "$name/$version"; const String website = "https://git.kittycat.homes/zoe/slothmu"; const Map defaultHeaders = { diff --git a/lib/main.dart b/lib/main.dart index 7408759..0384114 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,19 +7,23 @@ import 'business_logic/settings.dart' as settings; import 'package:flutter_localizations/flutter_localizations.dart'; import 'themes/themes.dart' as themes; import 'global.dart' as global; +import 'business_logic/auth/oauth.dart' as oauth; String _initRoute = "/"; ThemeData theme = themes.getTheme(themes.available[0]); Locale activeLocale = const Locale("en"); void main() async { + settings.saveAuthCode(""); Intl.defaultLocale = "en"; await settings.saveLocale("en"); activeLocale = await settings.loadLocale(); // check if all information is available if (await settings.loadAuthCode() == "") { - _initRoute = "/"; + _initRoute = "/login"; + } else { + await oauth.refreshToken(); } runApp(const Slothmu()); } diff --git a/lib/pages/timeline/timeline.dart b/lib/pages/timeline/timeline.dart index 07fa28d..44ee82a 100644 --- a/lib/pages/timeline/timeline.dart +++ b/lib/pages/timeline/timeline.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:localization/localization.dart'; -import '../../business_logic/settings.dart' as settings; import 'package:slothmu/partials/thread.dart'; +import '../../business_logic/timeline/timeline.dart' as tl; class Timeline extends StatefulWidget { const Timeline({Key? key}) : super(key: key); @@ -29,7 +29,9 @@ class _TimelineState extends State { Future fetchMore() async { loading = true; - final token = await settings.loadAuthCode(); + final response = await tl.getTimelineFromServer(); + print(response.body); + print(response.statusCode); setState(() { if (children.isNotEmpty) { children.removeAt(children.length - 1);