From a1f742b8d7614e91c26fab6940e13f5311ea0f44 Mon Sep 17 00:00:00 2001 From: Phill Date: Thu, 7 Feb 2019 18:07:29 +0000 Subject: [PATCH 01/18] Merge branches 'develop' and 'master' of https://github.com/phillwiggins/flutter_parse_sdk # Conflicts: # .idea/libraries/Dart_Packages.xml # lib/src/objects/parse_file.dart # lib/src/objects/parse_user.dart # pubspec.yaml --- CHANGELOG.md | 6 ++++++ README.md | 8 +++++--- lib/src/base/parse_constants.dart | 2 +- pubspec.yaml | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c237a8a4..04fefd911 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.0.11 +ParseFile fixed +Anonymous login +SecurityContext +CloudFunctions with objects + ## 1.0.10 Add ParseConfig. Fixed whereEqualsTo('', PARSEOBJECT) and other queries diff --git a/README.md b/README.md index d9927e47d..238b17b0b 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Want to get involved? Join our Slack channel and help out! (http://flutter-parse To install, either add to your pubspec.yaml ``` dependencies: - parse_server_sdk: ^1.0.10 + parse_server_sdk: ^1.0.11 ``` or clone this repository and add to your project. As this is an early development with multiple contributors, it is probably best to download/clone and keep updating as an when a new feature is added. @@ -33,8 +33,10 @@ Parse().initialize( ApplicationConstants.keyApplicationId, ApplicationConstants.keyParseServerUrl, masterKey: ApplicationConstants.keyParseMasterKey, - debug: true, - liveQuery: true); + clientKey: ApplicationConstants.keyParseClientKey, + debug: true, + liveQuery: true, + securityContext: securityContext); ``` ## Queries diff --git a/lib/src/base/parse_constants.dart b/lib/src/base/parse_constants.dart index d501b6029..2b43a59fc 100644 --- a/lib/src/base/parse_constants.dart +++ b/lib/src/base/parse_constants.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; // Library -const String keySdkVersion = '1.0.10'; +const String keySdkVersion = '1.0.11'; const String keyLibraryName = 'Flutter Parse SDK'; // End Points diff --git a/pubspec.yaml b/pubspec.yaml index 7ed5bd270..93c7c4254 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk description: Flutter plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 1.0.10 +version: 1.0.11 homepage: https://github.com/phillwiggins/flutter_parse_sdk author: PhillWiggins From 257f337845864df46eb34f56c9cd55a9bf37bb25 Mon Sep 17 00:00:00 2001 From: Phill Date: Thu, 7 Feb 2019 18:12:28 +0000 Subject: [PATCH 02/18] Merge branches 'develop' and 'master' of https://github.com/phillwiggins/flutter_parse_sdk # Conflicts: # .idea/libraries/Dart_Packages.xml # lib/src/objects/parse_file.dart # lib/src/objects/parse_user.dart # pubspec.yaml --- example/lib/diet_plan.dart | 8 ++++---- example/lib/main.dart | 23 ++++++++--------------- lib/{parse.dart => parse_server_sdk.dart} | 0 test/parse_client_configuration_test.dart | 12 +++++------- 4 files changed, 17 insertions(+), 26 deletions(-) rename lib/{parse.dart => parse_server_sdk.dart} (100%) diff --git a/example/lib/diet_plan.dart b/example/lib/diet_plan.dart index 52995379d..2a064a3b7 100644 --- a/example/lib/diet_plan.dart +++ b/example/lib/diet_plan.dart @@ -1,15 +1,15 @@ import 'dart:core'; -import 'package:parse_server_sdk/parse.dart'; +import 'package:parse_server_sdk/parse_server_sdk.dart'; class DietPlan extends ParseObject implements ParseCloneable { - DietPlan() : super(_keyTableName); - DietPlan.clone(): this(); + DietPlan.clone() : this(); /// Looks strangely hacky but due to Flutter not using reflection, we have to /// mimic a clone - @override clone(Map map) => DietPlan.clone()..fromJson(map); + @override + clone(Map map) => DietPlan.clone()..fromJson(map); static const String _keyTableName = 'Diet_Plans'; static const String keyName = 'Name'; diff --git a/example/lib/main.dart b/example/lib/main.dart index cee1b4c99..968fed0d3 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_plugin_example/application_constants.dart'; import 'package:flutter_plugin_example/diet_plan.dart'; -import 'package:parse_server_sdk/parse.dart'; +import 'package:parse_server_sdk/parse_server_sdk.dart'; void main() => runApp(new MyApp()); @@ -178,20 +178,13 @@ class _MyAppState extends State { } function() async { - var user = - ParseUser("TestFlutter", "TestPassword123", "TestFlutterSDK@gmail.com"); - await user.signUp(); - var loginResponse = await user.login(); - if (loginResponse.success) user = loginResponse.result; - - var customClient = ParseHTTPClient(); - customClient.additionalHeaders = { - keyHeaderSessionToken: ParseCoreData().sessionId - }; - var function = ParseCloudFunction('hello', client: customClient); - function.execute(); - - user.destroy(); + var function = ParseCloudFunction('hello'); + var result = await function.executeObjectFunction(); + if (result.success) { + if (result.result is ParseObject) { + print((result.result as ParseObject).className); + } + } } functionWithParameters() async { diff --git a/lib/parse.dart b/lib/parse_server_sdk.dart similarity index 100% rename from lib/parse.dart rename to lib/parse_server_sdk.dart diff --git a/test/parse_client_configuration_test.dart b/test/parse_client_configuration_test.dart index ae47e0f62..e017fb36f 100644 --- a/test/parse_client_configuration_test.dart +++ b/test/parse_client_configuration_test.dart @@ -1,10 +1,9 @@ +import 'package:parse_server_sdk/parse_server_sdk.dart'; import 'package:test/test.dart'; -import 'package:parse_server_sdk/parse.dart'; -void main(){ - test("testBuilder",() { - Parse().initialize("appId", - "serverUrl", +void main() { + test("testBuilder", () { + Parse().initialize("appId", "serverUrl", clientKey: "clientKey", liveQueryUrl: "liveQueryUrl", appName: "appName", @@ -20,6 +19,5 @@ void main(){ expect(ParseCoreData().masterKey, "masterKey"); expect(ParseCoreData().sessionId, "sessionId"); expect(ParseCoreData().debug, true); - }); -} \ No newline at end of file +} From 35b75389cd3ddcee13179c5c93f0e45df3705936 Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Fri, 8 Feb 2019 13:06:54 +0100 Subject: [PATCH 03/18] Clean-up usage of ParseHTTPClient objects. --- lib/parse_server_sdk.dart | 8 ++-- lib/src/objects/parse_config.dart | 4 +- lib/src/objects/parse_file.dart | 60 +++++++++++----------------- lib/src/objects/parse_function.dart | 2 +- lib/src/objects/parse_geo_point.dart | 6 +-- lib/src/objects/parse_object.dart | 10 ++--- lib/src/objects/parse_user.dart | 20 +++++----- 7 files changed, 47 insertions(+), 63 deletions(-) diff --git a/lib/parse_server_sdk.dart b/lib/parse_server_sdk.dart index 50ced0b16..a8f6fe0ab 100644 --- a/lib/parse_server_sdk.dart +++ b/lib/parse_server_sdk.dart @@ -98,12 +98,14 @@ class Parse { bool hasParseBeenInitialised() => _hasBeenInitialised; - Future healthCheck() async { + Future healthCheck({ParseHTTPClient client}) async { ParseResponse parseResponse; + ParseHTTPClient _client = + client ?? ParseHTTPClient(ParseCoreData().securityContext); try { - var response = await ParseHTTPClient(ParseCoreData().securityContext) - .get("${ParseCoreData().serverUrl}$keyEndPointHealth"); + var response = + await _client.get("${ParseCoreData().serverUrl}$keyEndPointHealth"); parseResponse = ParseResponse.handleResponse(this, response, returnAsResult: true); } on Exception catch (e) { diff --git a/lib/src/objects/parse_config.dart b/lib/src/objects/parse_config.dart index d2fbc4d67..aa27c88b6 100644 --- a/lib/src/objects/parse_config.dart +++ b/lib/src/objects/parse_config.dart @@ -1,12 +1,10 @@ part of flutter_parse_sdk; class ParseConfig extends ParseObject { - var _client = ParseHTTPClient(ParseCoreData().securityContext); - /// Creates an instance of ParseConfig so that you can grab all configs from the server ParseConfig({bool debug, ParseHTTPClient client}) : super('config') { if (debug != null) setDebug(debug); - if (client != null) setClient(client); + _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); } /// Gets all configs from the server diff --git a/lib/src/objects/parse_file.dart b/lib/src/objects/parse_file.dart index 5c31f87c1..00c0463da 100644 --- a/lib/src/objects/parse_file.dart +++ b/lib/src/objects/parse_file.dart @@ -1,28 +1,18 @@ part of flutter_parse_sdk; class ParseFile extends ParseObject { - File _file; - String _fileName; - String _fileUrl; + File file; + String name; + String url; @override String _path; - String get name => _fileName; - - String get url => _fileUrl; - - File get file => _file; - - set url(String url) => _fileUrl = url; - - set name(String name) => _fileName = name; - bool get saved => url != null; @override toJson({bool forApiRQ: false}) => - {'__type': keyFile, 'name': _fileName, 'url': _fileUrl}; + {'__type': keyFile, 'name': name, 'url': url}; @override String toString() => json.encode(toString()); @@ -30,54 +20,52 @@ class ParseFile extends ParseObject { /// Creates a new file /// /// {https://docs.parseplatform.org/rest/guide/#files/} - ParseFile(this._file, + ParseFile(this.file, {String name, String url, bool debug, ParseHTTPClient client}) : super(keyFile) { - client == null - ? _client = ParseHTTPClient(ParseCoreData().securityContext) - : _client = client; - _debug = isDebugEnabled(objectLevelDebug: debug); - if (_file != null) { - this._fileName = path.basename(_file.path); - this._path = 'files/$_fileName'; + _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); + + if (file != null) { + this.name = path.basename(file.path); + this._path = 'files/$name'; } else { - this._fileName = name; - this._fileUrl = url; + this.name = name; + this.url = url; } } Future loadStorage() async { Directory tempPath = await getTemporaryDirectory(); - if (_fileName == null) { - _file = null; + if (name == null) { + file = null; return this; } - File possibleFile = new File("${tempPath.path}/$_fileName"); + File possibleFile = new File("${tempPath.path}/$name"); bool exists = await possibleFile.exists(); if (exists) { - _file = possibleFile; + file = possibleFile; } else { - _file = null; + file = null; } return this; } Future download() async { - if (_fileUrl == null) { + if (url == null) { return this; } Directory tempPath = await getTemporaryDirectory(); - this._file = new File("${tempPath.path}/$_fileName"); - await _file.create(); + this.file = new File("${tempPath.path}/$name"); + await file.create(); - var response = await _client.get(_fileUrl); - _file.writeAsBytes(response.bodyBytes); + var response = await _client.get(url); + file.writeAsBytes(response.bodyBytes); return this; } @@ -88,13 +76,13 @@ class ParseFile extends ParseObject { return this; } - final ext = path.extension(_file.path).replaceAll('.', ''); + final ext = path.extension(file.path).replaceAll('.', ''); final headers = { HttpHeaders.contentTypeHeader: getContentType(ext) }; var uri = _client.data.serverUrl + "$_path"; - final body = await _file.readAsBytes(); + final body = await file.readAsBytes(); final response = await _client.post(uri, headers: headers, body: body); return handleResponse( this, response, ParseApiRQ.upload, _debug, className); diff --git a/lib/src/objects/parse_function.dart b/lib/src/objects/parse_function.dart index 6c0e7e632..716b280ec 100644 --- a/lib/src/objects/parse_function.dart +++ b/lib/src/objects/parse_function.dart @@ -14,7 +14,7 @@ class ParseCloudFunction extends ParseObject { _path = "/functions/$functionName"; if (debug != null) setDebug(debug); - if (client != null) setClient(client); + _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); } /// Executes a cloud function diff --git a/lib/src/objects/parse_geo_point.dart b/lib/src/objects/parse_geo_point.dart index f0ff5512b..2b1f07fda 100644 --- a/lib/src/objects/parse_geo_point.dart +++ b/lib/src/objects/parse_geo_point.dart @@ -14,10 +14,8 @@ class ParseGeoPoint extends ParseObject { _latitude = latitude; _longitude = longitude; - client == null - ? _client = ParseHTTPClient(ParseCoreData().securityContext) - : _client = client; _debug = isDebugEnabled(objectLevelDebug: debug); + _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); } double get latitude => _latitude; @@ -33,4 +31,4 @@ class ParseGeoPoint extends ParseObject { assert(value >= -180.0 || value <= 180.0); _longitude = value; } -} \ No newline at end of file +} diff --git a/lib/src/objects/parse_object.dart b/lib/src/objects/parse_object.dart index 3eea1587c..45a1143dc 100644 --- a/lib/src/objects/parse_object.dart +++ b/lib/src/objects/parse_object.dart @@ -1,7 +1,6 @@ part of flutter_parse_sdk; class ParseObject extends ParseBase implements ParseCloneable { - ParseObject.clone(String className) : this(className); @override @@ -16,21 +15,18 @@ class ParseObject extends ParseBase implements ParseCloneable { /// [String] className refers to the Table Name in your Parse Server, /// [bool] debug will overwrite the current default debug settings and /// [ParseHttpClient] can be overwritten to create your own HTTP Client - ParseObject(String className, {bool debug: false}) : super() { + ParseObject(String className, {bool debug: false, ParseHTTPClient client}) + : super() { setClassName(className); _path = "$keyEndPointClasses$className"; - setClient(ParseHTTPClient(ParseCoreData().securityContext)); setDebug(isDebugEnabled(objectLevelDebug: debug)); + _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); } void setDebug(bool debug) { _debug = debug; } - void setClient(ParseHTTPClient client) { - _client = client; - } - String toPointer() => parseEncode(this); /// Gets an object from the server using it's [String] objectId diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 86b469440..965181789 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -43,10 +43,8 @@ class ParseUser extends ParseObject implements ParseCloneable { ParseUser(String username, String password, String emailAddress, {bool debug, ParseHTTPClient client}) : super(keyClassUser) { - client == null - ? _client = ParseHTTPClient(ParseCoreData().securityContext) - : _client = client; _debug = isDebugEnabled(objectLevelDebug: debug); + _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); this.username = username; this.password = password; @@ -65,8 +63,10 @@ class ParseUser extends ParseObject implements ParseCloneable { /// fromServer can be called and an updated version of the [User] object will be /// returned static Future getCurrentUserFromServer( - {String token, bool debug}) async { + {String token, bool debug, ParseHTTPClient client}) async { bool _debug = isDebugEnabled(objectLevelDebug: debug); + ParseHTTPClient _client = + client ?? ParseHTTPClient(ParseCoreData().securityContext); // We can't get the current user and session without a sessionId if (token == null && ParseCoreData().sessionId == null) { @@ -85,8 +85,8 @@ class ParseUser extends ParseObject implements ParseCloneable { host: tempUri.host, path: "${tempUri.path}$keyEndPointUserName"); - final response = await ParseHTTPClient(ParseCoreData().securityContext) - .get(uri, headers: {keyHeaderSessionToken: token}); + final response = + await _client.get(uri, headers: {keyHeaderSessionToken: token}); return _handleResponse(_getEmptyUser(), response, ParseApiRQ.currentUser, _debug, _getEmptyUser().className); } on Exception catch (e) { @@ -271,12 +271,14 @@ class ParseUser extends ParseObject implements ParseCloneable { } /// Gets a list of all users (limited return) - static Future all() async { + static Future all({ParseHTTPClient client}) async { var emptyUser = ParseUser(null, null, null); + ParseHTTPClient _client = + client ?? ParseHTTPClient(ParseCoreData().securityContext); + try { - final response = await ParseHTTPClient(ParseCoreData().securityContext) - .get("${ParseCoreData().serverUrl}/$path"); + final response = await _client.get("${ParseCoreData().serverUrl}/$path"); ParseResponse parseResponse = ParseResponse.handleResponse(emptyUser, response); From 970335b94fc0ec92a53d02456d2db8c4838d4b71 Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Fri, 8 Feb 2019 13:50:20 +0100 Subject: [PATCH 04/18] Clean-up usage of debug switch. --- lib/parse_server_sdk.dart | 7 +++++-- lib/src/objects/parse_config.dart | 2 +- lib/src/objects/parse_function.dart | 2 +- lib/src/objects/parse_object.dart | 7 ++----- lib/src/objects/parse_user.dart | 5 +++-- lib/src/utils/parse_utils.dart | 6 ++---- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/parse_server_sdk.dart b/lib/parse_server_sdk.dart index a8f6fe0ab..c16f84427 100644 --- a/lib/parse_server_sdk.dart +++ b/lib/parse_server_sdk.dart @@ -98,8 +98,11 @@ class Parse { bool hasParseBeenInitialised() => _hasBeenInitialised; - Future healthCheck({ParseHTTPClient client}) async { + Future healthCheck( + {bool debug, ParseHTTPClient client}) async { ParseResponse parseResponse; + + bool _debug = isDebugEnabled(objectLevelDebug: debug); ParseHTTPClient _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); @@ -112,7 +115,7 @@ class Parse { parseResponse = ParseResponse.handleException(e); } - if (ParseCoreData().debug) { + if (_debug) { logger(ParseCoreData().appName, keyClassMain, ParseApiRQ.healthCheck.toString(), parseResponse); } diff --git a/lib/src/objects/parse_config.dart b/lib/src/objects/parse_config.dart index aa27c88b6..f575aca66 100644 --- a/lib/src/objects/parse_config.dart +++ b/lib/src/objects/parse_config.dart @@ -3,7 +3,7 @@ part of flutter_parse_sdk; class ParseConfig extends ParseObject { /// Creates an instance of ParseConfig so that you can grab all configs from the server ParseConfig({bool debug, ParseHTTPClient client}) : super('config') { - if (debug != null) setDebug(debug); + _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); } diff --git a/lib/src/objects/parse_function.dart b/lib/src/objects/parse_function.dart index 716b280ec..c271d1015 100644 --- a/lib/src/objects/parse_function.dart +++ b/lib/src/objects/parse_function.dart @@ -13,7 +13,7 @@ class ParseCloudFunction extends ParseObject { : super(functionName) { _path = "/functions/$functionName"; - if (debug != null) setDebug(debug); + _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); } diff --git a/lib/src/objects/parse_object.dart b/lib/src/objects/parse_object.dart index 45a1143dc..b64dc1324 100644 --- a/lib/src/objects/parse_object.dart +++ b/lib/src/objects/parse_object.dart @@ -19,12 +19,9 @@ class ParseObject extends ParseBase implements ParseCloneable { : super() { setClassName(className); _path = "$keyEndPointClasses$className"; - setDebug(isDebugEnabled(objectLevelDebug: debug)); - _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); - } - void setDebug(bool debug) { - _debug = debug; + _debug = isDebugEnabled(objectLevelDebug: debug); + _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); } String toPointer() => parseEncode(this); diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 965181789..cd58bb05a 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -271,9 +271,10 @@ class ParseUser extends ParseObject implements ParseCloneable { } /// Gets a list of all users (limited return) - static Future all({ParseHTTPClient client}) async { + static Future all({bool debug, ParseHTTPClient client}) async { var emptyUser = ParseUser(null, null, null); + bool _debug = isDebugEnabled(objectLevelDebug: debug); ParseHTTPClient _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); @@ -283,7 +284,7 @@ class ParseUser extends ParseObject implements ParseCloneable { ParseResponse parseResponse = ParseResponse.handleResponse(emptyUser, response); - if (ParseCoreData().debug) { + if (_debug) { logger(ParseCoreData().appName, keyClassUser, ParseApiRQ.getAll.toString(), parseResponse); } diff --git a/lib/src/utils/parse_utils.dart b/lib/src/utils/parse_utils.dart index 760354ab0..ebc423af9 100644 --- a/lib/src/utils/parse_utils.dart +++ b/lib/src/utils/parse_utils.dart @@ -4,10 +4,8 @@ part of flutter_parse_sdk; /// /// Debug can be set in 2 places, one global param in the Parse.initialise, and /// then can be overidden class by class -bool isDebugEnabled({objectLevelDebug: false}) { - bool debug = objectLevelDebug; - if (ParseCoreData().debug != null) debug = ParseCoreData().debug; - return debug; +bool isDebugEnabled({bool objectLevelDebug}) { + return objectLevelDebug ?? ParseCoreData().debug ?? false; } /// Converts the object to the correct value for JSON, From e2c1f692ec807d7b4b0eab0119ac87664455ded5 Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Fri, 8 Feb 2019 15:29:18 +0100 Subject: [PATCH 05/18] Fix some spellings. --- lib/parse_server_sdk.dart | 14 +++++------ ...e_livequery.dart => parse_live_query.dart} | 0 lib/src/network/parse_query.dart | 24 +++++++++---------- ...rse_clonable.dart => parse_cloneable.dart} | 0 lib/src/objects/parse_error.dart | 4 ++-- lib/src/objects/parse_user.dart | 2 +- lib/src/utils/parse_file_extensions.dart | 2 +- lib/src/utils/parse_utils.dart | 6 ++--- 8 files changed, 26 insertions(+), 26 deletions(-) rename lib/src/network/{parse_livequery.dart => parse_live_query.dart} (100%) rename lib/src/objects/{parse_clonable.dart => parse_cloneable.dart} (100%) diff --git a/lib/parse_server_sdk.dart b/lib/parse_server_sdk.dart index c16f84427..89ba5a595 100644 --- a/lib/parse_server_sdk.dart +++ b/lib/parse_server_sdk.dart @@ -22,13 +22,13 @@ part 'src/enums/parse_enum_api_rq.dart'; part 'src/network/parse_http_client.dart'; -part 'src/network/parse_livequery.dart'; +part 'src/network/parse_live_query.dart'; part 'src/network/parse_query.dart'; part 'src/objects/parse_base.dart'; -part 'src/objects/parse_clonable.dart'; +part 'src/objects/parse_cloneable.dart'; part 'src/objects/parse_config.dart'; @@ -58,11 +58,11 @@ part 'src/utils/parse_utils.dart'; class Parse { ParseCoreData data; - bool _hasBeenInitialised = false; + bool _hasBeenInitialized = false; - /// To initialise Parse Server in your application + /// To initialize Parse Server in your application /// - /// This should be initialised in MyApp() creation + /// This should be initialized in MyApp() creation /// /// ``` /// Parse().initialize( @@ -91,12 +91,12 @@ class Parse { ParseCoreData().initStorage(); - _hasBeenInitialised = true; + _hasBeenInitialized = true; return Parse(); } - bool hasParseBeenInitialised() => _hasBeenInitialised; + bool hasParseBeenInitialized() => _hasBeenInitialized; Future healthCheck( {bool debug, ParseHTTPClient client}) async { diff --git a/lib/src/network/parse_livequery.dart b/lib/src/network/parse_live_query.dart similarity index 100% rename from lib/src/network/parse_livequery.dart rename to lib/src/network/parse_live_query.dart diff --git a/lib/src/network/parse_query.dart b/lib/src/network/parse_query.dart index ce3958560..3d3813e74 100644 --- a/lib/src/network/parse_query.dart +++ b/lib/src/network/parse_query.dart @@ -27,7 +27,7 @@ class QueryBuilder { limiters['where'] = where; } - /// Orders the results ascedingly. + /// Sorts the results in ascending order. /// /// [String] order will be the column of the table that the results are /// ordered by @@ -35,7 +35,7 @@ class QueryBuilder { limiters["order"] = order; } - /// Orders the results descendingly. + /// Sorts the results descending order. /// /// [String] order will be the column of the table that the results are /// ordered by @@ -48,12 +48,12 @@ class QueryBuilder { /// [String] keys will only return the columns of a result you want the data for, /// this is useful for large objects void keysToReturn(List keys) { - limiters["keys"] = concatArray(keys); + limiters["keys"] = concatenateArray(keys); } /// Includes other ParseObjects stored as a Pointer void includeObject(List objectTypes) { - limiters["include"] = concatArray(objectTypes); + limiters["include"] = concatenateArray(objectTypes); } /// Returns an object where the [String] column starts with [value] @@ -131,7 +131,7 @@ class QueryBuilder { MapEntry(column, value), "\$nin")); } - /// Returns an object where the [String] column for the object has data correctley entered/saved + /// Returns an object where the [String] column for the object has data correctly entered/saved void whereValueExists(String column, bool value) { queries.add(_buildQueryWithColumnValueAndOperator( MapEntry(column, value), "\$exists")); @@ -211,7 +211,7 @@ class QueryBuilder { return queryBuilder; } - String concatArray(List queries) { + String concatenateArray(List queries) { String queryBuilder = ""; for (var item in queries) { @@ -252,17 +252,17 @@ class QueryBuilder { /// This joins queries that should be joined together... e.g. age > 10 && /// age < 20, this would be similar to age > 10 < 20 List _checkForMultipleColumnInstances(List queries) { - List sanitisedQueries = List(); + List sanitizedQueries = List(); List keysAlreadyCompacted = List(); // Run through each query for (var query in queries) { - // Add queries that don't need sanitising + // Add queries that don't need sanitizing if (query.key == _NO_OPERATOR_NEEDED || query.key == _SINGLE_QUERY) { - sanitisedQueries.add(MapEntry(_NO_OPERATOR_NEEDED, query.value)); + sanitizedQueries.add(MapEntry(_NO_OPERATOR_NEEDED, query.value)); } - // Check if query with same column name has been sanitised + // Check if query with same column name has been sanitized if (!keysAlreadyCompacted.contains(query.key) && query.key != _NO_OPERATOR_NEEDED && query.key != _SINGLE_QUERY) { @@ -290,11 +290,11 @@ class QueryBuilder { } } - sanitisedQueries.add(MapEntry(query.key, queryStart += "{$queryEnd}")); + sanitizedQueries.add(MapEntry(query.key, queryStart += "{$queryEnd}")); } } - return sanitisedQueries; + return sanitizedQueries; } /// Adds the limiters to the query, i.e. skip=10, limit=10 diff --git a/lib/src/objects/parse_clonable.dart b/lib/src/objects/parse_cloneable.dart similarity index 100% rename from lib/src/objects/parse_clonable.dart rename to lib/src/objects/parse_cloneable.dart diff --git a/lib/src/objects/parse_error.dart b/lib/src/objects/parse_error.dart index 3817213ec..e2d059206 100644 --- a/lib/src/objects/parse_error.dart +++ b/lib/src/objects/parse_error.dart @@ -48,7 +48,7 @@ class ParseError { 204: 'EmailMissing', 205: 'EmailNotFound', 206: 'SessionMissing', - 207: 'MustCreateUserThroughSignup', + 207: 'MustCreateUserThroughSignUp', 208: 'AccountAlreadyLinked', 209: 'InvalidSessionToken', 250: 'LinkedIdMissing', @@ -63,7 +63,7 @@ class ParseError { ParseError( {this.code = -1, - this.message = "Unkown error", + this.message = "Unknown error", this.isTypeOfException = false, bool debug: false}) { type = exceptions[code]; diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index cd58bb05a..85d233e07 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -33,7 +33,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Creates an instance of ParseUser /// /// Users can set whether debug should be set on this class with a [bool], - /// they can also create thier own custom version of [ParseHttpClient] + /// they can also create their own custom version of [ParseHttpClient] /// /// Creates a new user locally /// diff --git a/lib/src/utils/parse_file_extensions.dart b/lib/src/utils/parse_file_extensions.dart index 105d23e62..23fa1f147 100644 --- a/lib/src/utils/parse_file_extensions.dart +++ b/lib/src/utils/parse_file_extensions.dart @@ -25,7 +25,7 @@ String getContentType(String extension) { return contentType; } -/// Add content types based on extesion to a map +/// Add content types based on extension to a map Map _queryExtensions() { Map extensions = Map(); diff --git a/lib/src/utils/parse_utils.dart b/lib/src/utils/parse_utils.dart index ebc423af9..422e011e3 100644 --- a/lib/src/utils/parse_utils.dart +++ b/lib/src/utils/parse_utils.dart @@ -2,15 +2,15 @@ part of flutter_parse_sdk; /// Checks whether debug is enabled /// -/// Debug can be set in 2 places, one global param in the Parse.initialise, and -/// then can be overidden class by class +/// Debug can be set in 2 places, one global param in the Parse.initialize, and +/// then can be overwritten class by class bool isDebugEnabled({bool objectLevelDebug}) { return objectLevelDebug ?? ParseCoreData().debug ?? false; } /// Converts the object to the correct value for JSON, /// -/// Strings are wrapped with "" but ints and others are not +/// Strings are wrapped with "" but integers and others are not convertValueToCorrectType(dynamic value) { if (value is String && !value.contains('__type')) { return "\"$value\""; From 9e65690bc063f2d1897e3ab8bafedd0f29a3b915 Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Sun, 10 Feb 2019 13:07:09 +0100 Subject: [PATCH 06/18] Small clean-ups for storage. --- lib/parse_server_sdk.dart | 2 -- lib/src/data/parse_core_data.dart | 2 +- lib/src/objects/parse_base.dart | 12 +++--------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/parse_server_sdk.dart b/lib/parse_server_sdk.dart index 89ba5a595..c849972ce 100644 --- a/lib/parse_server_sdk.dart +++ b/lib/parse_server_sdk.dart @@ -89,8 +89,6 @@ class Parse { sessionId: sessionId, securityContext: securityContext); - ParseCoreData().initStorage(); - _hasBeenInitialized = true; return Parse(); diff --git a/lib/src/data/parse_core_data.dart b/lib/src/data/parse_core_data.dart index c19f82cd7..068552274 100644 --- a/lib/src/data/parse_core_data.dart +++ b/lib/src/data/parse_core_data.dart @@ -57,7 +57,7 @@ class ParseCoreData { } Future getStore() async { - return storage != null ? storage : await SharedPreferences.getInstance(); + return storage ?? (storage = await SharedPreferences.getInstance()); } @override diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index 55007efc3..acc2dd6ea 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -88,7 +88,7 @@ abstract class ParseBase { /// Returns the objects variables @protected - Map getObjectData() => _objectData != null ? _objectData : Map(); + Map getObjectData() => _objectData ?? Map(); /// Saves in storage @protected @@ -149,7 +149,7 @@ abstract class ParseBase { /// Replicates Android SDK pin process and saves object to storage Future unpin() async { if (objectId != null) { - await SharedPreferences.getInstance() + await ParseCoreData().getStore() ..remove(objectId); return true; } @@ -165,13 +165,7 @@ abstract class ParseBase { var itemFromStore = (await ParseCoreData().getStore()).getString(objectId); - if (itemFromStore != null) { - var map = json.decode(itemFromStore); - - if (map != null) { - return fromJson(map); - } - } + if (itemFromStore != null) return fromJson(json.decode(itemFromStore)); } return null; } From 241e8ce8828e443350fd6d4b89a298e393d3c25f Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Tue, 12 Feb 2019 12:59:13 +0100 Subject: [PATCH 07/18] Always send sessionId if available. --- lib/src/network/parse_http_client.dart | 12 ++++++++---- lib/src/objects/parse_user.dart | 20 ++++++-------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/lib/src/network/parse_http_client.dart b/lib/src/network/parse_http_client.dart index c84d9842d..8870b60ea 100644 --- a/lib/src/network/parse_http_client.dart +++ b/lib/src/network/parse_http_client.dart @@ -17,13 +17,17 @@ class ParseHTTPClient extends BaseClient { Future send(BaseRequest request) { request.headers[keyHeaderUserAgent] = _userAgent; request.headers[keyHeaderApplicationId] = data.applicationId; + if (data.sessionId != null) + request.headers[keyHeaderSessionToken] = data.sessionId; - if (data.clientKey != null) request.headers[keyHeaderClientKey] = data.clientKey; - if (data.masterKey != null) request.headers[keyHeaderMasterKey] = data.masterKey; + if (data.clientKey != null) + request.headers[keyHeaderClientKey] = data.clientKey; + if (data.masterKey != null) + request.headers[keyHeaderMasterKey] = data.masterKey; /// If developer wants to add custom headers, extend this class and add headers needed. - if (additionalHeaders != null && additionalHeaders.length > 0){ - additionalHeaders.forEach((k,v) => request.headers[k] = v); + if (additionalHeaders != null && additionalHeaders.length > 0) { + additionalHeaders.forEach((k, v) => request.headers[k] = v); } return _client.send(request); diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 85d233e07..bf8703aeb 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -63,20 +63,16 @@ class ParseUser extends ParseObject implements ParseCloneable { /// fromServer can be called and an updated version of the [User] object will be /// returned static Future getCurrentUserFromServer( - {String token, bool debug, ParseHTTPClient client}) async { + {bool debug, ParseHTTPClient client}) async { bool _debug = isDebugEnabled(objectLevelDebug: debug); ParseHTTPClient _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); // We can't get the current user and session without a sessionId - if (token == null && ParseCoreData().sessionId == null) { + if (ParseCoreData().sessionId == null) { return null; } - if (token == null) { - token = ParseCoreData().sessionId; - } - try { Uri tempUri = Uri.parse(ParseCoreData().serverUrl); @@ -85,8 +81,7 @@ class ParseUser extends ParseObject implements ParseCloneable { host: tempUri.host, path: "${tempUri.path}$keyEndPointUserName"); - final response = - await _client.get(uri, headers: {keyHeaderSessionToken: token}); + final response = await _client.get(uri); return _handleResponse(_getEmptyUser(), response, ParseApiRQ.currentUser, _debug, _getEmptyUser().className); } on Exception catch (e) { @@ -242,9 +237,7 @@ class ParseUser extends ParseObject implements ParseCloneable { var uri = _client.data.serverUrl + "$path/$objectId"; var body = json.encode(toJson(forApiRQ: true), toEncodable: dateTimeEncoder); - final response = await _client.put(uri, - headers: {keyHeaderSessionToken: _client.data.sessionId}, - body: body); + final response = await _client.put(uri, body: body); return _handleResponse( this, response, ParseApiRQ.save, _debug, className); } on Exception catch (e) { @@ -257,9 +250,8 @@ class ParseUser extends ParseObject implements ParseCloneable { Future destroy() async { if (objectId != null) { try { - final response = await _client.delete( - _client.data.serverUrl + "$path/$objectId", - headers: {keyHeaderSessionToken: _client.data.sessionId}); + final response = + await _client.delete(_client.data.serverUrl + "$path/$objectId"); return _handleResponse( this, response, ParseApiRQ.destroy, _debug, className); } on Exception catch (e) { From 8c0d4239e49bc63c1b06e8b055384ab45dafb2c7 Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Wed, 13 Feb 2019 21:41:46 +0100 Subject: [PATCH 08/18] Remove unused function initStorage. --- lib/src/data/parse_core_data.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/src/data/parse_core_data.dart b/lib/src/data/parse_core_data.dart index 068552274..89676cfd1 100644 --- a/lib/src/data/parse_core_data.dart +++ b/lib/src/data/parse_core_data.dart @@ -52,10 +52,6 @@ class ParseCoreData { this.sessionId = sessionId; } - void initStorage() async { - storage = await SharedPreferences.getInstance(); - } - Future getStore() async { return storage ?? (storage = await SharedPreferences.getInstance()); } From ae1cdad044d5a9483bc77c639e1d56608a69ec0d Mon Sep 17 00:00:00 2001 From: Phill Date: Sat, 16 Feb 2019 07:26:06 +0000 Subject: [PATCH 09/18] Fixed Parse logout and unpin --- lib/src/objects/parse_base.dart | 4 ++-- lib/src/objects/parse_user.dart | 2 +- test/parse_client_configuration_test.dart | 12 +++++------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/src/objects/parse_base.dart b/lib/src/objects/parse_base.dart index 55007efc3..71e21b8d6 100644 --- a/lib/src/objects/parse_base.dart +++ b/lib/src/objects/parse_base.dart @@ -147,10 +147,10 @@ abstract class ParseBase { /// Saves item to simple key pair value storage /// /// Replicates Android SDK pin process and saves object to storage - Future unpin() async { + Future unpin({String key}) async { if (objectId != null) { await SharedPreferences.getInstance() - ..remove(objectId); + ..remove(key ?? objectId); return true; } diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 86b469440..016cda8ac 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -198,7 +198,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Removes the current user from the session data logout() { _client.data.sessionId = null; - unpin(); + unpin(key: keyParseStoreUser); setObjectData(null); } diff --git a/test/parse_client_configuration_test.dart b/test/parse_client_configuration_test.dart index ae47e0f62..2f2909332 100644 --- a/test/parse_client_configuration_test.dart +++ b/test/parse_client_configuration_test.dart @@ -1,10 +1,9 @@ -import 'package:test/test.dart'; import 'package:parse_server_sdk/parse.dart'; +import 'package:test/test.dart'; -void main(){ - test("testBuilder",() { - Parse().initialize("appId", - "serverUrl", +void main() { + test("testBuilder", () { + Parse().initialize("appId", "serverUrl", clientKey: "clientKey", liveQueryUrl: "liveQueryUrl", appName: "appName", @@ -20,6 +19,5 @@ void main(){ expect(ParseCoreData().masterKey, "masterKey"); expect(ParseCoreData().sessionId, "sessionId"); expect(ParseCoreData().debug, true); - }); -} \ No newline at end of file +} From 311e25e63ac44a3f519a7ddd4665be864fa092ee Mon Sep 17 00:00:00 2001 From: Phill Date: Sat, 16 Feb 2019 07:33:43 +0000 Subject: [PATCH 10/18] Merge branches 'develop' and 'master' of https://github.com/phillwiggins/flutter_parse_sdk # Conflicts: # .idea/libraries/Dart_Packages.xml # lib/src/objects/parse_file.dart # lib/src/objects/parse_user.dart # pubspec.yaml --- test/parse_client_configuration_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parse_client_configuration_test.dart b/test/parse_client_configuration_test.dart index 2f2909332..e017fb36f 100644 --- a/test/parse_client_configuration_test.dart +++ b/test/parse_client_configuration_test.dart @@ -1,4 +1,4 @@ -import 'package:parse_server_sdk/parse.dart'; +import 'package:parse_server_sdk/parse_server_sdk.dart'; import 'package:test/test.dart'; void main() { From 82bbbaee0809585cd57a6f4bdd2aa37731105f9f Mon Sep 17 00:00:00 2001 From: Phill Date: Sat, 16 Feb 2019 07:36:40 +0000 Subject: [PATCH 11/18] v1.0.12 - Fixed login --- CHANGELOG.md | 3 +++ README.md | 2 +- example/lib/main.dart | 9 +++++++-- lib/src/base/parse_constants.dart | 2 +- pubspec.yaml | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04fefd911..d649e3e48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.0.12 +Fixed logout + ## 1.0.11 ParseFile fixed Anonymous login diff --git a/README.md b/README.md index 238b17b0b..cc6138763 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Want to get involved? Join our Slack channel and help out! (http://flutter-parse To install, either add to your pubspec.yaml ``` dependencies: - parse_server_sdk: ^1.0.11 + parse_server_sdk: ^1.0.12 ``` or clone this repository and add to your project. As this is an early development with multiple contributors, it is probably best to download/clone and keep updating as an when a new feature is added. diff --git a/example/lib/main.dart b/example/lib/main.dart index 968fed0d3..99468d277 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -155,9 +155,14 @@ class _MyAppState extends State { // Best practice for starting the app. This will check for a valid user user = await ParseUser.currentUser(); await user.logout(); - user = await ParseUser.currentUser(); - response = await ParseUser.getCurrentUserFromServer(); + user = + ParseUser("TestFlutter", "TestPassword123", "phill.wiggins@gmail.com"); + response = await user.login(); + if (response.success) user = response.result; + + response = await ParseUser.getCurrentUserFromServer( + token: user.get(keyHeaderSessionToken)); if (response.success) user = response.result; response = await user.save(); diff --git a/lib/src/base/parse_constants.dart b/lib/src/base/parse_constants.dart index 2b43a59fc..63a14a91f 100644 --- a/lib/src/base/parse_constants.dart +++ b/lib/src/base/parse_constants.dart @@ -1,7 +1,7 @@ part of flutter_parse_sdk; // Library -const String keySdkVersion = '1.0.11'; +const String keySdkVersion = '1.0.12'; const String keyLibraryName = 'Flutter Parse SDK'; // End Points diff --git a/pubspec.yaml b/pubspec.yaml index 93c7c4254..b8f53edbe 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk description: Flutter plugin for Parse Server, (https://parseplatform.org), (https://back4app.com) -version: 1.0.11 +version: 1.0.12 homepage: https://github.com/phillwiggins/flutter_parse_sdk author: PhillWiggins From 0e8734c3db38b08433a04c15eb7cf88000eae12e Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Sat, 16 Feb 2019 14:23:20 +0100 Subject: [PATCH 12/18] Allow given token in getCurrentUserFromServer. --- lib/src/network/parse_http_client.dart | 3 ++- lib/src/objects/parse_user.dart | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/src/network/parse_http_client.dart b/lib/src/network/parse_http_client.dart index 8870b60ea..b4ef85064 100644 --- a/lib/src/network/parse_http_client.dart +++ b/lib/src/network/parse_http_client.dart @@ -17,7 +17,8 @@ class ParseHTTPClient extends BaseClient { Future send(BaseRequest request) { request.headers[keyHeaderUserAgent] = _userAgent; request.headers[keyHeaderApplicationId] = data.applicationId; - if (data.sessionId != null) + if ((data.sessionId != null) && + (request.headers[keyHeaderSessionToken] == null)) request.headers[keyHeaderSessionToken] = data.sessionId; if (data.clientKey != null) diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 45063878d..11ce1e1aa 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -63,16 +63,21 @@ class ParseUser extends ParseObject implements ParseCloneable { /// fromServer can be called and an updated version of the [User] object will be /// returned static Future getCurrentUserFromServer( - {bool debug, ParseHTTPClient client}) async { + {String token, bool debug, ParseHTTPClient client}) async { bool _debug = isDebugEnabled(objectLevelDebug: debug); ParseHTTPClient _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); // We can't get the current user and session without a sessionId - if (ParseCoreData().sessionId == null) { + if ((ParseCoreData().sessionId == null) && (token == null)) { return null; } + final Map headers = {}; + if (token != null) { + headers[keyHeaderSessionToken] = token; + } + try { Uri tempUri = Uri.parse(ParseCoreData().serverUrl); @@ -81,7 +86,7 @@ class ParseUser extends ParseObject implements ParseCloneable { host: tempUri.host, path: "${tempUri.path}$keyEndPointUserName"); - final response = await _client.get(uri); + final response = await _client.get(uri, headers: headers); return _handleResponse(_getEmptyUser(), response, ParseApiRQ.currentUser, _debug, _getEmptyUser().className); } on Exception catch (e) { From daf8aca43390f4902f243c387c8f55089d93de0b Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Sun, 17 Feb 2019 00:43:02 +0100 Subject: [PATCH 13/18] Make automatic sending of sessionId optional. --- lib/parse_server_sdk.dart | 11 ++++++++--- lib/src/data/parse_core_data.dart | 4 ++++ lib/src/network/parse_http_client.dart | 10 +++++++--- lib/src/objects/parse_config.dart | 9 +++++++-- lib/src/objects/parse_file.dart | 12 ++++++++++-- lib/src/objects/parse_function.dart | 9 +++++++-- lib/src/objects/parse_geo_point.dart | 9 +++++++-- lib/src/objects/parse_object.dart | 9 +++++++-- lib/src/objects/parse_user.dart | 17 ++++++++++++----- 9 files changed, 69 insertions(+), 21 deletions(-) diff --git a/lib/parse_server_sdk.dart b/lib/parse_server_sdk.dart index c849972ce..a6c9ff267 100644 --- a/lib/parse_server_sdk.dart +++ b/lib/parse_server_sdk.dart @@ -79,6 +79,7 @@ class Parse { String clientKey, String masterKey, String sessionId, + bool autoSendSessionId, SecurityContext securityContext}) { ParseCoreData.init(appId, serverUrl, debug: debug, @@ -87,6 +88,7 @@ class Parse { masterKey: masterKey, clientKey: clientKey, sessionId: sessionId, + autoSendSessionId: autoSendSessionId, securityContext: securityContext); _hasBeenInitialized = true; @@ -97,12 +99,15 @@ class Parse { bool hasParseBeenInitialized() => _hasBeenInitialized; Future healthCheck( - {bool debug, ParseHTTPClient client}) async { + {bool debug, ParseHTTPClient client, bool autoSendSessionId}) async { ParseResponse parseResponse; bool _debug = isDebugEnabled(objectLevelDebug: debug); - ParseHTTPClient _client = - client ?? ParseHTTPClient(ParseCoreData().securityContext); + ParseHTTPClient _client = client ?? + ParseHTTPClient( + autoSendSessionId: + autoSendSessionId ?? ParseCoreData().autoSendSessionId, + securityContext: ParseCoreData().securityContext); try { var response = diff --git a/lib/src/data/parse_core_data.dart b/lib/src/data/parse_core_data.dart index 89676cfd1..b5b0bccee 100644 --- a/lib/src/data/parse_core_data.dart +++ b/lib/src/data/parse_core_data.dart @@ -17,6 +17,7 @@ class ParseCoreData { masterKey, clientKey, sessionId, + autoSendSessionId, securityContext}) { _instance = ParseCoreData._init(appId, serverUrl); @@ -26,6 +27,8 @@ class ParseCoreData { if (clientKey != null) _instance.clientKey = clientKey; if (masterKey != null) _instance.masterKey = masterKey; if (sessionId != null) _instance.sessionId = sessionId; + if (autoSendSessionId != null) + _instance.autoSendSessionId = autoSendSessionId; if (securityContext != null) _instance.securityContext = securityContext; } @@ -36,6 +39,7 @@ class ParseCoreData { String masterKey; String clientKey; String sessionId; + bool autoSendSessionId; SecurityContext securityContext; bool debug; SharedPreferences storage; diff --git a/lib/src/network/parse_http_client.dart b/lib/src/network/parse_http_client.dart index b4ef85064..a31da62da 100644 --- a/lib/src/network/parse_http_client.dart +++ b/lib/src/network/parse_http_client.dart @@ -3,12 +3,15 @@ part of flutter_parse_sdk; /// Creates a custom version of HTTP Client that has Parse Data Preset class ParseHTTPClient extends BaseClient { final Client _client; + final bool _autoSendSessionId; final String _userAgent = "$keyLibraryName $keySdkVersion"; ParseCoreData data = ParseCoreData(); Map additionalHeaders; - ParseHTTPClient([SecurityContext securityContext]) - : _client = securityContext != null + ParseHTTPClient( + {bool autoSendSessionId = false, SecurityContext securityContext}) + : _autoSendSessionId = autoSendSessionId, + _client = securityContext != null ? IOClient(HttpClient(context: securityContext)) : IOClient(); @@ -17,7 +20,8 @@ class ParseHTTPClient extends BaseClient { Future send(BaseRequest request) { request.headers[keyHeaderUserAgent] = _userAgent; request.headers[keyHeaderApplicationId] = data.applicationId; - if ((data.sessionId != null) && + if ((_autoSendSessionId == true) && + (data.sessionId != null) && (request.headers[keyHeaderSessionToken] == null)) request.headers[keyHeaderSessionToken] = data.sessionId; diff --git a/lib/src/objects/parse_config.dart b/lib/src/objects/parse_config.dart index f575aca66..14e7b025e 100644 --- a/lib/src/objects/parse_config.dart +++ b/lib/src/objects/parse_config.dart @@ -2,9 +2,14 @@ part of flutter_parse_sdk; class ParseConfig extends ParseObject { /// Creates an instance of ParseConfig so that you can grab all configs from the server - ParseConfig({bool debug, ParseHTTPClient client}) : super('config') { + ParseConfig({bool debug, ParseHTTPClient client, bool autoSendSessionId}) + : super('config') { _debug = isDebugEnabled(objectLevelDebug: debug); - _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); + _client = client ?? + ParseHTTPClient( + autoSendSessionId: + autoSendSessionId ?? ParseCoreData().autoSendSessionId, + securityContext: ParseCoreData().securityContext); } /// Gets all configs from the server diff --git a/lib/src/objects/parse_file.dart b/lib/src/objects/parse_file.dart index 00c0463da..531d1422e 100644 --- a/lib/src/objects/parse_file.dart +++ b/lib/src/objects/parse_file.dart @@ -21,10 +21,18 @@ class ParseFile extends ParseObject { /// /// {https://docs.parseplatform.org/rest/guide/#files/} ParseFile(this.file, - {String name, String url, bool debug, ParseHTTPClient client}) + {String name, + String url, + bool debug, + ParseHTTPClient client, + bool autoSendSessionId}) : super(keyFile) { _debug = isDebugEnabled(objectLevelDebug: debug); - _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); + _client = client ?? + ParseHTTPClient( + autoSendSessionId: + autoSendSessionId ?? ParseCoreData().autoSendSessionId, + securityContext: ParseCoreData().securityContext); if (file != null) { this.name = path.basename(file.path); diff --git a/lib/src/objects/parse_function.dart b/lib/src/objects/parse_function.dart index c271d1015..7b23368f7 100644 --- a/lib/src/objects/parse_function.dart +++ b/lib/src/objects/parse_function.dart @@ -9,12 +9,17 @@ class ParseCloudFunction extends ParseObject { /// Creates a new cloud function object /// /// {https://docs.parseplatform.org/cloudcode/guide/} - ParseCloudFunction(this.functionName, {bool debug, ParseHTTPClient client}) + ParseCloudFunction(this.functionName, + {bool debug, ParseHTTPClient client, bool autoSendSessionId}) : super(functionName) { _path = "/functions/$functionName"; _debug = isDebugEnabled(objectLevelDebug: debug); - _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); + _client = client ?? + ParseHTTPClient( + autoSendSessionId: + autoSendSessionId ?? ParseCoreData().autoSendSessionId, + securityContext: ParseCoreData().securityContext); } /// Executes a cloud function diff --git a/lib/src/objects/parse_geo_point.dart b/lib/src/objects/parse_geo_point.dart index 2b1f07fda..e541fcefb 100644 --- a/lib/src/objects/parse_geo_point.dart +++ b/lib/src/objects/parse_geo_point.dart @@ -9,13 +9,18 @@ class ParseGeoPoint extends ParseObject { {double latitude = 0.0, double longitude = 0.0, bool debug, - ParseHTTPClient client}) + ParseHTTPClient client, + bool autoSendSessionId}) : super(keyGeoPoint) { _latitude = latitude; _longitude = longitude; _debug = isDebugEnabled(objectLevelDebug: debug); - _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); + _client = client ?? + ParseHTTPClient( + autoSendSessionId: + autoSendSessionId ?? ParseCoreData().autoSendSessionId, + securityContext: ParseCoreData().securityContext); } double get latitude => _latitude; diff --git a/lib/src/objects/parse_object.dart b/lib/src/objects/parse_object.dart index b64dc1324..5c28f8e8a 100644 --- a/lib/src/objects/parse_object.dart +++ b/lib/src/objects/parse_object.dart @@ -15,13 +15,18 @@ class ParseObject extends ParseBase implements ParseCloneable { /// [String] className refers to the Table Name in your Parse Server, /// [bool] debug will overwrite the current default debug settings and /// [ParseHttpClient] can be overwritten to create your own HTTP Client - ParseObject(String className, {bool debug: false, ParseHTTPClient client}) + ParseObject(String className, + {bool debug: false, ParseHTTPClient client, bool autoSendSessionId}) : super() { setClassName(className); _path = "$keyEndPointClasses$className"; _debug = isDebugEnabled(objectLevelDebug: debug); - _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); + _client = client ?? + ParseHTTPClient( + autoSendSessionId: + autoSendSessionId ?? ParseCoreData().autoSendSessionId, + securityContext: ParseCoreData().securityContext); } String toPointer() => parseEncode(this); diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 11ce1e1aa..fee5fc2bc 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -44,7 +44,10 @@ class ParseUser extends ParseObject implements ParseCloneable { {bool debug, ParseHTTPClient client}) : super(keyClassUser) { _debug = isDebugEnabled(objectLevelDebug: debug); - _client = client ?? ParseHTTPClient(ParseCoreData().securityContext); + _client = client ?? + ParseHTTPClient( + autoSendSessionId: true, + securityContext: ParseCoreData().securityContext); this.username = username; this.password = password; @@ -65,8 +68,10 @@ class ParseUser extends ParseObject implements ParseCloneable { static Future getCurrentUserFromServer( {String token, bool debug, ParseHTTPClient client}) async { bool _debug = isDebugEnabled(objectLevelDebug: debug); - ParseHTTPClient _client = - client ?? ParseHTTPClient(ParseCoreData().securityContext); + ParseHTTPClient _client = client ?? + ParseHTTPClient( + autoSendSessionId: true, + securityContext: ParseCoreData().securityContext); // We can't get the current user and session without a sessionId if ((ParseCoreData().sessionId == null) && (token == null)) { @@ -272,8 +277,10 @@ class ParseUser extends ParseObject implements ParseCloneable { var emptyUser = ParseUser(null, null, null); bool _debug = isDebugEnabled(objectLevelDebug: debug); - ParseHTTPClient _client = - client ?? ParseHTTPClient(ParseCoreData().securityContext); + ParseHTTPClient _client = client ?? + ParseHTTPClient( + autoSendSessionId: true, + securityContext: ParseCoreData().securityContext); try { final response = await _client.get("${ParseCoreData().serverUrl}/$path"); From 17972fc6033d36b1db2ccbded031b7d6fea13523 Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Sun, 17 Feb 2019 09:19:20 +0100 Subject: [PATCH 14/18] Add autoSendSessionId parameter to README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 238b17b0b..b71995592 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ Parse().initialize( clientKey: ApplicationConstants.keyParseClientKey, debug: true, liveQuery: true, - securityContext: securityContext); + autoSendSessionId: true, + securityContext: securityContext); ``` ## Queries From fcea37ef50e7b6d322b4d83e62e92e8967bc643e Mon Sep 17 00:00:00 2001 From: Rick Spencer Date: Tue, 19 Feb 2019 18:55:31 -0500 Subject: [PATCH 15/18] added call to logout endpoint --- lib/src/base/parse_constants.dart | 1 + lib/src/enums/parse_enum_api_rq.dart | 1 + lib/src/objects/parse_user.dart | 34 ++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/lib/src/base/parse_constants.dart b/lib/src/base/parse_constants.dart index 2b43a59fc..8a0f0d5d0 100644 --- a/lib/src/base/parse_constants.dart +++ b/lib/src/base/parse_constants.dart @@ -7,6 +7,7 @@ const String keyLibraryName = 'Flutter Parse SDK'; // End Points const String keyEndPointUserName = '/users/me'; const String keyEndPointLogin = '/login'; +const String keyEndPointLogout = '/logout'; const String keyEndPointUsers = '/users'; const String keyEndPointVerificationEmail = '/verificationEmailRequest'; const String keyEndPointRequestPasswordReset = '/requestPasswordReset'; diff --git a/lib/src/enums/parse_enum_api_rq.dart b/lib/src/enums/parse_enum_api_rq.dart index 0d9d93db5..6b6f2b338 100644 --- a/lib/src/enums/parse_enum_api_rq.dart +++ b/lib/src/enums/parse_enum_api_rq.dart @@ -12,6 +12,7 @@ enum ParseApiRQ { currentUser, signUp, login, + logout, loginAnonymous, verificationEmailRequest, requestPasswordReset, diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index fee5fc2bc..45dd46bdd 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -200,11 +200,35 @@ class ParseUser extends ParseObject implements ParseCloneable { } } - /// Removes the current user from the session data - logout() { - _client.data.sessionId = null; - unpin(key: keyParseStoreUser); - setObjectData(null); + /// Sends a request to delete the sessions token from the + /// server. Will also delete the local user data unless + /// deleteLocalUserData is false. + logout({bool deleteLocalUserData = true}) async { + if (deleteLocalUserData) { + _client.data.sessionId = null; + unpin(key: keyParseStoreUser); + setObjectData(null); + } + + try { + if (username == null) return null; + + Uri tempUri = Uri.parse(_client.data.serverUrl); + + Uri url = Uri( + scheme: tempUri.scheme, + host: tempUri.host, + path: "${tempUri.path}$keyEndPointLogout"); + + final response = await _client.post( + url, + ); + + return _handleResponse( + this, response, ParseApiRQ.logout, _debug, className); + } on Exception catch (e) { + return _handleException(e, ParseApiRQ.logout, _debug, className); + } } /// Sends a verification email to the users email address From 8cef05dffeaa934451991dac7c9cd86409bfa604 Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Wed, 20 Feb 2019 12:06:06 +0100 Subject: [PATCH 16/18] Fix ParseUser.logout method. --- lib/src/objects/parse_user.dart | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 45dd46bdd..e516c6c36 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -203,16 +203,16 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Sends a request to delete the sessions token from the /// server. Will also delete the local user data unless /// deleteLocalUserData is false. - logout({bool deleteLocalUserData = true}) async { - if (deleteLocalUserData) { + Future logout({bool deleteLocalUserData = true}) async { + final String sessionId = _client.data.sessionId; + + if (deleteLocalUserData == true) { _client.data.sessionId = null; unpin(key: keyParseStoreUser); setObjectData(null); } try { - if (username == null) return null; - Uri tempUri = Uri.parse(_client.data.serverUrl); Uri url = Uri( @@ -220,9 +220,8 @@ class ParseUser extends ParseObject implements ParseCloneable { host: tempUri.host, path: "${tempUri.path}$keyEndPointLogout"); - final response = await _client.post( - url, - ); + final response = + await _client.post(url, headers: {keyHeaderSessionToken: sessionId}); return _handleResponse( this, response, ParseApiRQ.logout, _debug, className); From 4735f2cfa70bf0ec276c7e4055f07f2df3672fae Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Wed, 20 Feb 2019 12:17:58 +0100 Subject: [PATCH 17/18] sessionId has to be delete at all circumstances. --- lib/src/objects/parse_user.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index e516c6c36..7fc4ac533 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -206,8 +206,9 @@ class ParseUser extends ParseObject implements ParseCloneable { Future logout({bool deleteLocalUserData = true}) async { final String sessionId = _client.data.sessionId; + _client.data.sessionId = null; + if (deleteLocalUserData == true) { - _client.data.sessionId = null; unpin(key: keyParseStoreUser); setObjectData(null); } From 799c83bffdd856a283ca137424953011f4ec9eec Mon Sep 17 00:00:00 2001 From: Christoph Bayer Date: Fri, 22 Feb 2019 14:09:59 +0100 Subject: [PATCH 18/18] Handle sessionToken correctly in ParseUser --- lib/src/base/parse_constants.dart | 1 + lib/src/objects/parse_user.dart | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/src/base/parse_constants.dart b/lib/src/base/parse_constants.dart index 8a0f0d5d0..592b07a9e 100644 --- a/lib/src/base/parse_constants.dart +++ b/lib/src/base/parse_constants.dart @@ -22,6 +22,7 @@ const String keyVarUpdatedAt = 'updatedAt'; const String keyVarUsername = 'username'; const String keyVarEmail = 'email'; const String keyVarPassword = 'password'; +const String keyVarSessionToken = 'sessionToken'; const String keyVarAcl = 'ACL'; // Classes diff --git a/lib/src/objects/parse_user.dart b/lib/src/objects/parse_user.dart index 7fc4ac533..7c7b05e7f 100644 --- a/lib/src/objects/parse_user.dart +++ b/lib/src/objects/parse_user.dart @@ -30,6 +30,11 @@ class ParseUser extends ParseObject implements ParseCloneable { set emailAddress(String emailAddress) => set(keyVarEmail, emailAddress); + String get sessionToken => super.get(keyVarSessionToken); + + set sessionToken(String sessionToken) => + set(keyVarSessionToken, sessionToken); + /// Creates an instance of ParseUser /// /// Users can set whether debug should be set on this class with a [bool], @@ -41,7 +46,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// is required as well to create a full new user object on ParseServer. Only /// username and password is required to login ParseUser(String username, String password, String emailAddress, - {bool debug, ParseHTTPClient client}) + {String sessionToken, bool debug, ParseHTTPClient client}) : super(keyClassUser) { _debug = isDebugEnabled(objectLevelDebug: debug); _client = client ?? @@ -52,6 +57,7 @@ class ParseUser extends ParseObject implements ParseCloneable { this.username = username; this.password = password; this.emailAddress = emailAddress; + this.sessionToken = sessionToken; } ParseUser.forQuery() : super(keyClassUser); @@ -105,7 +111,7 @@ class ParseUser extends ParseObject implements ParseCloneable { /// Current user is stored locally, but in case of a server update [bool] /// fromServer can be called and an updated version of the [User] object will be /// returned - static currentUser() { + static Future currentUser() { return _getUserFromLocalStore(); } @@ -207,6 +213,7 @@ class ParseUser extends ParseObject implements ParseCloneable { final String sessionId = _client.data.sessionId; _client.data.sessionId = null; + ParseCoreData().setSessionId(null); if (deleteLocalUserData == true) { unpin(key: keyParseStoreUser); @@ -366,7 +373,8 @@ class ParseUser extends ParseObject implements ParseCloneable { Map responseData = JsonDecoder().convert(response.body); if (responseData.containsKey(keyVarObjectId)) { parseResponse.result.fromJson(responseData); - ParseCoreData().setSessionId(responseData[keyParamSessionToken]); + user.sessionToken = responseData[keyParamSessionToken]; + ParseCoreData().setSessionId(user.sessionToken); } if (type == ParseApiRQ.getAll || type == ParseApiRQ.destroy) {