From 1e0f11351b59ab6e2d98cf3482f1c583679c6a36 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 18 Mar 2024 14:08:59 +0700 Subject: [PATCH] v3.5.0 --- CHANGELOG.md | 20 + README.md | 57 ++- example/main.dart | 42 +- example/pubspec.lock | 360 +++++++++++++++++- example/pubspec.yaml | 31 -- lib/enums/wp_route_type.dart | 4 + lib/helpers/typedefs.dart | 2 +- .../responses/wp_user_login_response.dart | 41 +- .../responses/wp_user_register_response.dart | 41 +- lib/models/wp_meta_meta.dart | 2 +- lib/models/wp_user.dart | 88 +++++ lib/networking/network_manager.dart | 280 ++++++++++---- lib/wp_json_api.dart | 72 +++- pubspec.lock | 358 ++++++++++++++++- pubspec.yaml | 3 +- 15 files changed, 1222 insertions(+), 179 deletions(-) create mode 100644 lib/models/wp_user.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 733374d..34e1c88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +## [3.5.0] - 2024-03-18 + +* Breaking change `WPJsonAPI.initWith` is now `WPJsonAPI.init` +* Refactor project +* Ability to save user token for future requests +* New WpUser model for user data +* New wcRegister method for networking class +* Add more data to `WpUserLoginResponse` and `WpUserInfoResponse` +* Added `version` to `WpJsonAPI` class +* New `WPJsonAPI.wpLogin` method to login a user +* New `WPJsonAPI.wpLogout` method to logout a user +* New `WPJsonAPI.wpUserLoggedIn` method to check if a user is logged in +* New `WPJsonAPI.wpUser` method to get the current user +* New `WPJsonAPI.wpUserId` method to get the current user's ID +* New `WPJsonAPI.wpUserToken` method to get the current user's token +* New `WPJsonAPI.wpAuth` method to authenticate the previously logged in user +* Added Storage key to `WPJsonAPI` class +* New docs added to Readme +* Dependency updates + ## [3.4.0] - 2024-03-15 * Added new networking methods for WooCommerce Points and Rewards diff --git a/README.md b/README.md index 9ccac69..bf976c9 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ In your flutter project add the dependency: ``` dart dependencies: ... - wp_json_api: ^3.4.0 + wp_json_api: ^3.5.0 ``` ### Usage example # @@ -45,7 +45,7 @@ import 'package:wp_json_api/wp_json_api.dart'; void main() { -WPJsonAPI.instance.initWith(baseUrl: "https://mysite.com"); +WPJsonAPI.instance.init(baseUrl: "https://mysite.com"); ... ``` @@ -115,29 +115,26 @@ WPUserRegisterResponse wpUserRegisterResponse = await WPJsonAPI.instance .api((request) => request.wpRegister( email: email, password: password, - username: username + // username: username // optional - the library will automatically generate a username if not provided )); ``` #### WordPress - Get Users Info - Used to get a WordPress users info -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to get the users info ``` dart WPUserInfoResponse wpUserInfoResponse = await WPJsonAPI.instance - .api((request) => request.wpGetUserInfo( - userToken - )); + .api((request) => request.wpGetUserInfo()); ``` #### WordPress - Update Users Info - Used to update a WordPress users info -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to update the users info ``` dart WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse = await WPJsonAPI.instance .api((request) => request.wpUpdateUserInfo( - userToken, firstName: firstName, lastName: lastName, displayName: displayName @@ -146,55 +143,61 @@ WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse = await WPJsonAPI.instance #### WordPress - Update users password - Used to update a users password -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to update the users password ``` dart WPUserResetPasswordResponse wpUserResetPasswordResponse = await WPJsonAPI.instance .api((request) => request.wpResetPassword( - userToken, password: password )); ``` #### WordPress - Add a role to a user - Used to add a role to a user in WordPress -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to add a role to the user ``` dart WPUserAddRoleResponse wpUserAddRoleResponse = await WPJsonAPI.instance .api((request) => request.wpUserAddRole( - userToken, role: "customer" // e.g. customer, subscriber )); ``` #### WordPress - Remove a role from a user - Used to remove a role from a user in WordPress -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to remove a role from the user ``` dart WPUserRemoveRoleResponse wpUserRemoveRoleResponse = await WPJsonAPI.instance .api((request) => request.wpUserRemoveRole( - userToken, role: "customer" // e.g. customer, subscriber )); ``` #### WordPress - Delete a user - Used to delete a user in WordPress -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to delete the user - You can pass an optional argument 'reassign' to reassign posts and links to new User ID. ``` dart WPUserDeleteResponse wpUserDeleteResponse = await WPJsonAPI.instance - .api((request) => request.wpUserDelete( - userToken - )); + .api((request) => request.wpUserDelete()); +``` + +#### WooCommerce - Register +- Used to register a user + +``` dart +WPUserRegisterResponse wpUserRegisterResponse = await WPJsonAPI.instance + .api((request) => request.wpRegister( + email: email, + password: password + )); ``` #### WooCommerce - Get users info in WooCommerce - Used to get WooCommerce info for a given user -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to get the users WooCommerce info ``` dart WCCustomerInfoResponse wcCustomerInfoResponse = await WPJsonAPI.instance @@ -206,12 +209,11 @@ WCCustomerInfoResponse wcCustomerInfoResponse = await WPJsonAPI.instance #### WooCommerce - Update users info in WooCommerce - Used to update a users WooCommerce details - All the parameter are optional so if you wanted to just update the name, you could just add first_name and last_name -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to update the users WooCommerce info ``` dart WCCustomerUpdatedResponse wcCustomerUpdatedResponse = await WPJsonAPI.instance .api((request) => request.wcUpdateCustomerInfo( - userToken, firstName: firstName, lastName: lastName, displayName: displayName, @@ -242,23 +244,20 @@ WCCustomerUpdatedResponse wcCustomerUpdatedResponse = await WPJsonAPI.instance #### WooCommerce Points and Rewards - Get user's points - This is used to get the user's current points in the [WooCommerce Points and Rewards](https://woo.com/products/woocommerce-points-and-rewards/) plugin -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to get the users points ``` dart WcPointsAndRewardUser wcPointsAndRewardUser = await WPJsonAPI.instance - .api((request) => request.wcPointsAndRewardsUser( - userToken - )); + .api((request) => request.wcPointsAndRewardsUser()); ``` #### WooCommerce Points and Rewards - Calculate the value of points - This is used to calculate the value of points in the [WooCommerce Points and Rewards](https://woo.com/products/woocommerce-points-and-rewards/) plugin -- The first parameter is the **userToken** which is returned from the login/register response. You should have this saved somewhere e.g. shared_pref +- After you login/register, you can all this method to calculate the value of points ``` dart WcPointsAndRewardCalculatePoints wcPointsAndRewardsCalculatePoints = await WPJsonAPI.instance .api((request) => request.wcPointsAndRewardsCalculatePoints( - userToken, points: 100 )); ``` @@ -270,6 +269,6 @@ For help getting started with WooSignal, view our To use this plugin, add `wp_json_api` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). ## Note -Install our WordPress plugin "[WP JSON API](https://woosignal.com/plugins/wordpress/wp-json-api)" v3.3.2 to use this flutter plugin. +Install our WordPress plugin "[WP JSON API](https://woosignal.com/plugins/wordpress/wp-json-api)" v3.4.0 to use this flutter plugin. Disclaimer: This plugin is not affiliated with or supported by Automattic, Inc. All logos and trademarks are the property of their respective owners. diff --git a/example/main.dart b/example/main.dart index dcdbde8..2e51a04 100644 --- a/example/main.dart +++ b/example/main.dart @@ -29,8 +29,8 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - late TextEditingController _tfEmailController; - late TextEditingController _tfPasswordController; + TextEditingController _tfEmailController = TextEditingController(); + TextEditingController _tfPasswordController = TextEditingController(); @override void initState() { @@ -40,10 +40,7 @@ class _MyHomePageState extends State { // FIRST ON YOUR WORDPRESS STORE // LINK https://woosignal.com/plugins/wordpress/wp-json-api - WPJsonAPI.instance.initWith(baseUrl: "http://mysite.com"); - - _tfEmailController = TextEditingController(); - _tfPasswordController = TextEditingController(); + WPJsonAPI.instance.init(baseUrl: "http://mysite.com"); } _login() async { @@ -60,24 +57,23 @@ class _MyHomePageState extends State { print(e); } - if (wpUserLoginResponse != null) { - print(wpUserLoginResponse.data?.userToken); - print(wpUserLoginResponse.data?.userId); - - // GET USER INFO - WPUserInfoResponse? wpUserInfoResponse = - await WPJsonAPI.instance.api((request) { - return request.wpGetUserInfo(wpUserLoginResponse!.data!.userToken!); - }); - - if (wpUserInfoResponse != null) { - print(wpUserInfoResponse.data?.firstName); - print(wpUserInfoResponse.data?.lastName); - } else { - print("something went wrong"); - } - } else { + if (wpUserLoginResponse == null) { print("invalid login details"); + return; + } + + print(wpUserLoginResponse.data?.userToken); + print(wpUserLoginResponse.data?.userId); + + // GET USER INFO + WPUserInfoResponse? wpUserInfoResponse = + await WPJsonAPI.instance.api((request) => request.wpGetUserInfo()); + + if (wpUserInfoResponse != null) { + print(wpUserInfoResponse.data?.firstName); + print(wpUserInfoResponse.data?.lastName); + } else { + print("something went wrong"); } } diff --git a/example/pubspec.lock b/example/pubspec.lock index 1a14362..9c33896 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + animate_do: + dependency: transitive + description: + name: animate_do + sha256: "7a3162729f0ea042f9dd84da217c5bde5472ad9cef644079929d4304a5dc4ca0" + url: "https://pub.dev" + source: hosted + version: "3.3.4" async: dependency: transitive description: @@ -49,6 +57,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.4.1" + equatable: + dependency: transitive + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" fake_async: dependency: transitive description: @@ -57,16 +73,122 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_dotenv: + dependency: transitive + description: + name: flutter_dotenv + sha256: "9357883bdd153ab78cbf9ffa07656e336b8bbb2b5a3ca596b0b27e119f7c7d77" + url: "https://pub.dev" + source: hosted + version: "5.1.0" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + flutter_secure_storage: + dependency: transitive + description: + name: flutter_secure_storage + sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685 + url: "https://pub.dev" + source: hosted + version: "9.0.0" + flutter_secure_storage_linux: + dependency: transitive + description: + name: flutter_secure_storage_linux + sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + flutter_secure_storage_macos: + dependency: transitive + description: + name: flutter_secure_storage_macos + sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c + url: "https://pub.dev" + source: hosted + version: "3.0.1" + flutter_secure_storage_platform_interface: + dependency: transitive + description: + name: flutter_secure_storage_platform_interface + sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + flutter_secure_storage_web: + dependency: transitive + description: + name: flutter_secure_storage_web + sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_secure_storage_windows: + dependency: transitive + description: + name: flutter_secure_storage_windows + sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + flutter_staggered_grid_view: + dependency: transitive + description: + name: flutter_staggered_grid_view + sha256: "19e7abb550c96fbfeb546b23f3ff356ee7c59a019a651f8f102a4ba9b7349395" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + flutter_styled_toast: + dependency: transitive + description: + name: flutter_styled_toast + sha256: e667f13a665820eb0fa8506547e47eacbcddf1948d6d3036cfd3b089bd4b0516 + url: "https://pub.dev" + source: hosted + version: "2.2.1" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + get_time_ago: + dependency: transitive + description: + name: get_time_ago + sha256: "982d1b82c7b2cbb8f443cee5db9508e6c8efb7f7be5b659f17d3575c340d09d3" + url: "https://pub.dev" + source: hosted + version: "1.3.1" http_parser: dependency: transitive description: @@ -75,6 +197,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + intl: + dependency: transitive + description: + name: intl + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + url: "https://pub.dev" + source: hosted + version: "0.18.1" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" leak_tracker: dependency: transitive description: @@ -123,6 +261,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.11.0" + nylo_support: + dependency: transitive + description: + name: nylo_support + sha256: "2927b62a1dfbed8e85847e9460d0b8bcca3ec61b4d72318f3835dbbad6980fb0" + url: "https://pub.dev" + source: hosted + version: "5.56.1" + page_transition: + dependency: transitive + description: + name: page_transition + sha256: dee976b1f23de9bbef5cd512fe567e9f6278caee11f5eaca9a2115c19dc49ef6 + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: @@ -131,6 +285,166 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.0" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + platform: + dependency: transitive + description: + name: platform + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + url: "https://pub.dev" + source: hosted + version: "3.1.4" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pretty_dio_logger: + dependency: transitive + description: + name: pretty_dio_logger + sha256: "00b80053063935cf9a6190da344c5373b9d0e92da4c944c878ff2fbef0ef6dc2" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + pull_to_refresh_flutter3: + dependency: transitive + description: + name: pull_to_refresh_flutter3 + sha256: "37a88d901cca9a46dbdd46523de8e7b35a3e58634a0e775b1a5904981f69b353" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + recase: + dependency: transitive + description: + name: recase + sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 + url: "https://pub.dev" + source: hosted + version: "4.1.0" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + url: "https://pub.dev" + source: hosted + version: "0.27.7" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" + url: "https://pub.dev" + source: hosted + version: "2.3.5" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" + url: "https://pub.dev" + source: hosted + version: "2.3.0" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + skeletonizer: + dependency: transitive + description: + name: skeletonizer + sha256: "2eb80153c80507359ff05f6a18ed50ae0bafa1b999aa867a8cef0a53387b5650" + url: "https://pub.dev" + source: hosted + version: "1.1.0" sky_engine: dependency: transitive description: flutter @@ -184,6 +498,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.1" + theme_provider: + dependency: transitive + description: + name: theme_provider + sha256: "6a2839ee1bd539ceb789f25ea9696fe90f9dfad28e3228f209b8ff9255c58099" + url: "https://pub.dev" + source: hosted + version: "0.6.0" typed_data: dependency: transitive description: @@ -192,6 +514,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + validated: + dependency: transitive + description: + name: validated + sha256: f4da18b50fa2aeda8d2f6e55bdf73759593abe3f9dd4aeece4e98bf3438e6a9f + url: "https://pub.dev" + source: hosted + version: "2.0.0" vector_math: dependency: transitive description: @@ -208,13 +538,37 @@ packages: url: "https://pub.dev" source: hosted version: "13.0.0" + web: + dependency: transitive + description: + name: web + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + url: "https://pub.dev" + source: hosted + version: "0.5.1" + win32: + dependency: transitive + description: + name: win32 + sha256: "8cb58b45c47dcb42ab3651533626161d6b67a2921917d8d429791f76972b3480" + url: "https://pub.dev" + source: hosted + version: "5.3.0" wp_json_api: dependency: "direct dev" description: path: ".." relative: true source: path - version: "3.3.4" + version: "3.5.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + url: "https://pub.dev" + source: hosted + version: "1.0.4" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=1.17.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 93056c6..ca4b56b 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,34 +18,3 @@ dev_dependencies: flutter: uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages \ No newline at end of file diff --git a/lib/enums/wp_route_type.dart b/lib/enums/wp_route_type.dart index 4863d74..949dca7 100644 --- a/lib/enums/wp_route_type.dart +++ b/lib/enums/wp_route_type.dart @@ -62,7 +62,11 @@ enum WPRouteType { /// For WooCommerce WCCustomerUpdateInfo, + /// Route type [WPRouteType.WCPointsAndRewardsUser] is used to get a customers points. + /// For WooCommerce Points and Rewards WCPointsAndRewardsUser, + /// Route type [WPRouteType.WCPointsAndRewardsUser] is used to get the value of a customers points. + /// For WooCommerce Points and Rewards WCPointsAndRewardsCalculatePoints, } diff --git a/lib/helpers/typedefs.dart b/lib/helpers/typedefs.dart index 5f8f2ef..64d9ffe 100644 --- a/lib/helpers/typedefs.dart +++ b/lib/helpers/typedefs.dart @@ -13,7 +13,7 @@ // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -import 'package:wp_json_api/networking/network_manager.dart'; +import '/networking/network_manager.dart'; /// The [RequestCallback] is used for calling a method in [WPAppNetworkManager] /// This is used on the api method in wp_json_api diff --git a/lib/models/responses/wp_user_login_response.dart b/lib/models/responses/wp_user_login_response.dart index eb42397..ad921b9 100644 --- a/lib/models/responses/wp_user_login_response.dart +++ b/lib/models/responses/wp_user_login_response.dart @@ -41,13 +41,46 @@ class Data { int? userId; String? userToken; int? expiry; + String? email; + String? username; + String? firstName; + String? lastName; + String? avatar; + String? createdAt; - Data({this.userId, this.userToken, this.expiry}); + Data( + {this.userId, + this.userToken, + this.expiry, + this.email, + this.username, + this.firstName, + this.lastName, + this.avatar, + this.createdAt}); Data.fromJson(Map json) { userId = json['user_id']; userToken = json['user_token']; expiry = json['expiry']; + if (json.containsKey('email')) { + email = json['email']; + } + if (json.containsKey('username')) { + username = json['username']; + } + if (json.containsKey('first_name')) { + firstName = json['first_name']; + } + if (json.containsKey('last_name')) { + lastName = json['last_name']; + } + if (json.containsKey('avatar')) { + avatar = json['avatar']; + } + if (json.containsKey('created_at')) { + createdAt = json['created_at']; + } } Map toJson() { @@ -55,6 +88,12 @@ class Data { data['user_id'] = this.userId; data['user_token'] = this.userToken; data['expiry'] = this.expiry; + data['email'] = this.email; + data['username'] = this.username; + data['first_name'] = this.firstName; + data['last_name'] = this.lastName; + data['avatar'] = this.avatar; + data['created_at'] = this.createdAt; return data; } } diff --git a/lib/models/responses/wp_user_register_response.dart b/lib/models/responses/wp_user_register_response.dart index c85a6a5..ff9170d 100644 --- a/lib/models/responses/wp_user_register_response.dart +++ b/lib/models/responses/wp_user_register_response.dart @@ -41,13 +41,46 @@ class Data { int? userId; String? userToken; int? expiry; + String? email; + String? username; + String? firstName; + String? lastName; + String? avatar; + String? createdAt; - Data({this.userId, this.userToken, this.expiry}); + Data( + {this.userId, + this.userToken, + this.expiry, + this.email, + this.username, + this.firstName, + this.lastName, + this.avatar, + this.createdAt}); Data.fromJson(Map json) { userId = json['user_id']; userToken = json['user_token']; expiry = json['expiry']; + if (json.containsKey('email')) { + email = json['email']; + } + if (json.containsKey('username')) { + username = json['username']; + } + if (json.containsKey('first_name')) { + firstName = json['first_name']; + } + if (json.containsKey('last_name')) { + lastName = json['last_name']; + } + if (json.containsKey('avatar')) { + avatar = json['avatar']; + } + if (json.containsKey('created_at')) { + createdAt = json['created_at']; + } } Map toJson() { @@ -55,6 +88,12 @@ class Data { data['id'] = this.userId; data['user_token'] = this.userToken; data['expiry'] = this.expiry; + data['email'] = this.email; + data['username'] = this.username; + data['first_name'] = this.firstName; + data['last_name'] = this.lastName; + data['avatar'] = this.avatar; + data['created_at'] = this.createdAt; return data; } } diff --git a/lib/models/wp_meta_meta.dart b/lib/models/wp_meta_meta.dart index 810a0c2..e883ad1 100644 --- a/lib/models/wp_meta_meta.dart +++ b/lib/models/wp_meta_meta.dart @@ -13,7 +13,7 @@ // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -import 'package:wp_json_api/enums/wp_meta_data_action_type.dart'; +import '/enums/wp_meta_data_action_type.dart'; class WpMetaData { String? key; diff --git a/lib/models/wp_user.dart b/lib/models/wp_user.dart new file mode 100644 index 0000000..a1b633b --- /dev/null +++ b/lib/models/wp_user.dart @@ -0,0 +1,88 @@ +// Copyright (c) 2024, WooSignal Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms are permitted +// provided that the above copyright notice and this paragraph are +// duplicated in all such forms and that any documentation, +// advertising materials, and other materials related to such +// distribution and use acknowledge that the software was developed +// by the WooSignal. The name of the +// WooSignal may not be used to endorse or promote products derived +// from this software without specific prior written permission. +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +import 'package:nylo_support/helpers/helper.dart'; +import '/models/responses/wp_user_login_response.dart'; +import '/models/responses/wp_user_register_response.dart'; + +class WpUser extends Model { + int? id; + String? token; + String? email; + String? username; + String? firstName; + String? lastName; + String? avatar; + String? createdAt; + + WpUser( + {this.id, + this.token, + this.email, + this.username, + this.firstName, + this.lastName, + this.avatar, + this.createdAt}); + + /// Creates a [WpUser] from a JSON object + WpUser.fromJson(Map json) { + id = json['id']; + token = json['token']; + email = json['email']; + username = json['username']; + firstName = json['first_name']; + lastName = json['last_name']; + avatar = json['avatar']; + createdAt = json['created_at']; + } + + /// Creates a [WpUser] from a [WPUserRegisterResponse] + WpUser.fromWPUserRegisterResponse( + WPUserRegisterResponse wpUserRegisterResponse) { + id = wpUserRegisterResponse.data?.userId; + token = wpUserRegisterResponse.data?.userToken; + email = wpUserRegisterResponse.data?.email; + username = wpUserRegisterResponse.data?.username; + firstName = wpUserRegisterResponse.data?.firstName; + lastName = wpUserRegisterResponse.data?.lastName; + avatar = wpUserRegisterResponse.data?.avatar; + createdAt = wpUserRegisterResponse.data?.createdAt; + } + + /// Creates a [WpUser] from a [WPUserLoginResponse] + WpUser.fromWPUserLoginResponse(WPUserLoginResponse wpUserLoginResponse) { + id = wpUserLoginResponse.data?.userId; + token = wpUserLoginResponse.data?.userToken; + email = wpUserLoginResponse.data?.email; + username = wpUserLoginResponse.data?.username; + firstName = wpUserLoginResponse.data?.firstName; + lastName = wpUserLoginResponse.data?.lastName; + avatar = wpUserLoginResponse.data?.avatar; + createdAt = wpUserLoginResponse.data?.createdAt; + } + + /// Converts the [WpUser] to a JSON object + toJson() => { + 'id': id, + 'token': token, + 'email': email, + 'username': username, + 'first_name': firstName, + 'last_name': lastName, + 'avatar': avatar, + 'created_at': createdAt + }; +} diff --git a/lib/networking/network_manager.dart b/lib/networking/network_manager.dart index ba472fa..2df0879 100644 --- a/lib/networking/network_manager.dart +++ b/lib/networking/network_manager.dart @@ -15,38 +15,41 @@ import 'dart:developer'; import 'dart:io'; +import 'dart:math' as math; import 'package:dio/dio.dart'; -import 'package:wp_json_api/enums/wp_auth_type.dart'; -import 'package:wp_json_api/exceptions/empty_username_exception.dart'; -import 'package:wp_json_api/exceptions/existing_user_email_exception.dart'; -import 'package:wp_json_api/exceptions/existing_user_login_exception.dart'; -import 'package:wp_json_api/exceptions/incorrect_password_exception.dart'; -import 'package:wp_json_api/exceptions/invalid_email_exception.dart'; -import 'package:wp_json_api/exceptions/invalid_nonce_exception.dart'; -import 'package:wp_json_api/exceptions/invalid_params_exception.dart'; -import 'package:wp_json_api/exceptions/invalid_user_token_exception.dart'; -import 'package:wp_json_api/exceptions/invalid_username_exception.dart'; -import 'package:wp_json_api/exceptions/user_already_exist_exception.dart'; -import 'package:wp_json_api/exceptions/username_taken_exception.dart'; -import 'package:wp_json_api/exceptions/woocommerce_not_found_exception.dart'; -import 'package:wp_json_api/models/responses/wc_customer_info_response.dart'; -import 'package:wp_json_api/models/responses/wc_customer_updated_response.dart'; -import 'package:wp_json_api/models/responses/wc_points_and_rewards_calculate_points.dart'; -import 'package:wp_json_api/models/responses/wc_points_and_rewards_user.dart'; -import 'package:wp_json_api/models/responses/wp_nonce_response.dart'; -import 'package:wp_json_api/models/responses/wp_nonce_verified_response.dart'; -import 'package:wp_json_api/models/responses/wp_user_add_role_response.dart'; -import 'package:wp_json_api/models/responses/wp_user_delete_response.dart'; -import 'package:wp_json_api/models/responses/wp_user_info_updated_response.dart'; -import 'package:wp_json_api/models/responses/wp_user_login_response.dart'; -import 'package:wp_json_api/models/responses/wp_user_register_response.dart'; -import 'package:wp_json_api/models/responses/wp_user_remove_role_response.dart'; -import 'package:wp_json_api/models/responses/wp_user_reset_password_response.dart'; -import 'package:wp_json_api/models/wp_meta_meta.dart'; -import 'package:wp_json_api/wp_json_api.dart'; -import 'package:wp_json_api/enums/wp_route_type.dart'; -import 'package:wp_json_api/models/responses/wp_user_info_response.dart'; +import 'package:nylo_support/helpers/helper.dart'; +import '/enums/wp_auth_type.dart'; +import '/exceptions/empty_username_exception.dart'; +import '/exceptions/existing_user_email_exception.dart'; +import '/exceptions/existing_user_login_exception.dart'; +import '/exceptions/incorrect_password_exception.dart'; +import '/exceptions/invalid_email_exception.dart'; +import '/exceptions/invalid_nonce_exception.dart'; +import '/exceptions/invalid_params_exception.dart'; +import '/exceptions/invalid_user_token_exception.dart'; +import '/exceptions/invalid_username_exception.dart'; +import '/exceptions/user_already_exist_exception.dart'; +import '/exceptions/username_taken_exception.dart'; +import '/exceptions/woocommerce_not_found_exception.dart'; +import '/models/responses/wc_customer_info_response.dart'; +import '/models/responses/wc_customer_updated_response.dart'; +import '/models/responses/wc_points_and_rewards_calculate_points.dart'; +import '/models/responses/wc_points_and_rewards_user.dart'; +import '/models/responses/wp_nonce_response.dart'; +import '/models/responses/wp_nonce_verified_response.dart'; +import '/models/responses/wp_user_add_role_response.dart'; +import '/models/responses/wp_user_delete_response.dart'; +import '/models/responses/wp_user_info_updated_response.dart'; +import '/models/responses/wp_user_login_response.dart'; +import '/models/responses/wp_user_register_response.dart'; +import '/models/responses/wp_user_remove_role_response.dart'; +import '/models/responses/wp_user_reset_password_response.dart'; +import '/models/wp_meta_meta.dart'; +import '/models/wp_user.dart'; +import '/wp_json_api.dart'; +import '/enums/wp_route_type.dart'; +import '/models/responses/wp_user_info_response.dart'; /// A networking class to manage all the APIs from "wp_json_api" class WPAppNetworkManager { @@ -72,7 +75,8 @@ class WPAppNetworkManager { String? username, required String password, WPAuthType authType = WPAuthType.WpEmail, - String? tokenExpiryAt}) async { + String? tokenExpiryAt, + bool saveTokenToLocalStorage = true}) async { // Get nonce from WordPress WPNonceResponse wpNonceResponse = await wpNonce(); @@ -81,7 +85,7 @@ class WPAppNetworkManager { if (username != null) payload["username"] = username; if (email != null) payload["email"] = email; payload["password"] = password; - payload["nonce"] = wpNonceResponse.data!.nonce; + payload["nonce"] = wpNonceResponse.data?.nonce; if (tokenExpiryAt != null) payload["expiry"] = tokenExpiryAt; // send http request @@ -93,9 +97,18 @@ class WPAppNetworkManager { ); // return response - return _jsonHasBadStatus(json) - ? this._throwExceptionForStatusCode(json) - : WPUserLoginResponse.fromJson(json); + if (_jsonHasBadStatus(json)) { + return _throwExceptionForStatusCode(json); + } + WPUserLoginResponse wpUserLoginResponse = + WPUserLoginResponse.fromJson(json); + String? userToken = wpUserLoginResponse.data?.userToken; + + if (userToken != null && saveTokenToLocalStorage) { + WpUser wpUser = WpUser.fromWPUserLoginResponse(wpUserLoginResponse); + await WPJsonAPI.wpLogin(wpUser); + } + return wpUserLoginResponse; } /// Sends a request to register a user in WordPress with the following @@ -113,17 +126,25 @@ class WPAppNetworkManager { Future wpRegister( {required String email, required String password, - required String username, - String? expiry}) async { + String? username, + String? expiry, + Map? args, + bool saveTokenToLocalStorage = true}) async { // Get nonce from WordPress WPNonceResponse wpNonceResponse = await wpNonce(); + if (username == null) { + username = (email.replaceAll(RegExp(r'([@.])'), "")) + _randomString(4); + } + // Creates payload for register Map payload = { "email": email, "password": password, "username": username, - "nonce": wpNonceResponse.data!.nonce + "wc_register": false, + "nonce": wpNonceResponse.data?.nonce, + "args": args }; if (expiry != null) payload["expiry"] = expiry; @@ -135,9 +156,77 @@ class WPAppNetworkManager { ); // return response - return _jsonHasBadStatus(json) - ? this._throwExceptionForStatusCode(json) - : WPUserRegisterResponse.fromJson(json); + if (_jsonHasBadStatus(json)) { + return _throwExceptionForStatusCode(json); + } + WPUserRegisterResponse wPUserRegisterResponse = + WPUserRegisterResponse.fromJson(json); + String? userToken = wPUserRegisterResponse.data?.userToken; + + if (userToken != null && saveTokenToLocalStorage) { + WpUser wpUser = WpUser.fromWPUserRegisterResponse(wPUserRegisterResponse); + await WPJsonAPI.wpLogin(wpUser); + } + return wPUserRegisterResponse; + } + + /// Sends a request to register a user in WooCommerce with the following + /// parameters [username], [email] and [password]. + /// You can optionally set an [expiry] for the token expiry like "+1 day". + /// + /// Returns a [WPUserRegisterResponse] future. + /// Throws an [UsernameTakenException] if username is taken + /// [InvalidNonceException] if nonce token is not valid + /// [ExistingUserLoginException] if user login exists + /// [ExistingUserEmailException] if that email is in use + /// [UserAlreadyExistException] if a user was found with the same email + /// [EmptyUsernameException] if the username field has empty + /// [Exception] if fails. + Future wcRegister( + {required String email, + required String password, + String? username, + String? expiry, + Map? args, + bool saveTokenToLocalStorage = true}) async { + // Get nonce from WordPress + WPNonceResponse wpNonceResponse = await wpNonce(); + + if (username == null) { + username = (email.replaceAll(RegExp(r'([@.])'), "")) + _randomString(4); + } + + // Creates payload for register + Map payload = { + "email": email, + "password": password, + "username": username, + "wc_register": true, // This is the key to register a user in WooCommerce + "nonce": wpNonceResponse.data?.nonce, + "args": args + }; + if (expiry != null) payload["expiry"] = expiry; + + // send http request + final json = await _http( + method: "POST", + url: _urlForRouteType(WPRouteType.UserRegister), + body: payload, + ); + + // return response + if (_jsonHasBadStatus(json)) { + return _throwExceptionForStatusCode(json); + } + WPUserRegisterResponse wPUserRegisterResponse = + WPUserRegisterResponse.fromJson(json); + String? userToken = wPUserRegisterResponse.data?.userToken; + + if (userToken != null && saveTokenToLocalStorage) { + WpUser wpUser = WpUser.fromWPUserRegisterResponse(wPUserRegisterResponse); + await WPJsonAPI.wpLogin(wpUser); + } + return wPUserRegisterResponse; } /// Makes a request to get a valid nonce code @@ -182,13 +271,13 @@ class WPAppNetworkManager { /// /// Returns a [WPUserInfoResponse] future. /// Throws an [Exception] if fails - Future wpGetUserInfo(String userToken) async { + Future wpGetUserInfo({String? userToken}) async { // send http request final json = await _http( - method: "POST", - url: _urlForRouteType(WPRouteType.UserInfo), - userToken: userToken, - ); + method: "POST", + url: _urlForRouteType(WPRouteType.UserInfo), + userToken: userToken, + shouldAuthRequest: true); // return response return _jsonHasBadStatus(json) @@ -202,8 +291,9 @@ class WPAppNetworkManager { /// /// Returns a [WPUserInfoUpdatedResponse] future. /// Throws an [Exception] if fails. - Future wpUpdateUserInfo(userToken, - {String? firstName, + Future wpUpdateUserInfo( + {String? userToken, + String? firstName, String? lastName, String? displayName, List? metaData}) async { @@ -222,6 +312,7 @@ class WPAppNetworkManager { method: "POST", url: _urlForRouteType(WPRouteType.UserUpdateInfo), userToken: userToken, + shouldAuthRequest: true, body: payload, ); @@ -236,8 +327,8 @@ class WPAppNetworkManager { /// /// Returns a [WPUserInfoUpdatedResponse] future. /// Throws an [Exception] if fails. - Future wpUserAddRole(userToken, - {required String role}) async { + Future wpUserAddRole( + {required String role, String? userToken}) async { Map payload = {}; payload["role"] = role; @@ -246,6 +337,7 @@ class WPAppNetworkManager { method: "POST", url: _urlForRouteType(WPRouteType.UserAddRole), userToken: userToken, + shouldAuthRequest: true, body: payload, ); @@ -255,12 +347,18 @@ class WPAppNetworkManager { : WPUserAddRoleResponse.fromJson(json); } + /// Logs out the user by deleting the user token from the local storage + wpLogout() async { + await NyStorage.delete(WPJsonAPI.storageKey()); + } + /// Sends a request to delete a WordPress user. Include a valid /// [userToken] and an optional [reassign] argument to send a successful request. /// /// Returns a [WPUserDeleteResponse] future. /// Throws an [Exception] if fails. - Future wpUserDelete(userToken, {int? reassign}) async { + Future wpUserDelete( + {String? userToken, int? reassign}) async { Map payload = {}; if (reassign != null) { payload["reassign"] = reassign; @@ -271,6 +369,7 @@ class WPAppNetworkManager { method: "POST", url: _urlForRouteType(WPRouteType.UserDelete), userToken: userToken, + shouldAuthRequest: true, body: payload, ); @@ -285,8 +384,8 @@ class WPAppNetworkManager { /// /// Returns a [WPUserInfoUpdatedResponse] future. /// Throws an [Exception] if fails. - Future wpUserRemoveRole(userToken, - {required String role}) async { + Future wpUserRemoveRole( + {required String role, String? userToken}) async { Map payload = {}; payload["role"] = role; @@ -295,6 +394,7 @@ class WPAppNetworkManager { method: "POST", url: _urlForRouteType(WPRouteType.UserRemoveRole), userToken: userToken, + shouldAuthRequest: true, body: payload, ); @@ -308,19 +408,19 @@ class WPAppNetworkManager { /// /// Returns a [WCCustomerInfoResponse] future. /// Throws an [Exception] if fails. - Future wpResetPassword( - String userToken, { + Future wpResetPassword({ required String password, + String? userToken, }) async { Map payload = {"password": password}; // send http request final json = await _http( - method: "POST", - url: _urlForRouteType(WPRouteType.UserUpdatePassword), - body: payload, - userToken: userToken, - ); + method: "POST", + url: _urlForRouteType(WPRouteType.UserUpdatePassword), + body: payload, + userToken: userToken, + shouldAuthRequest: true); // return response return _jsonHasBadStatus(json) @@ -332,13 +432,13 @@ class WPAppNetworkManager { /// /// Returns a [WCCustomerInfoResponse] future. /// Throws an [Exception] if fails. - Future wcCustomerInfo(String userToken) async { + Future wcCustomerInfo({String? userToken}) async { // send http request final json = await _http( - method: "POST", - url: _urlForRouteType(WPRouteType.WCCustomerInfo), - userToken: userToken, - ); + method: "POST", + url: _urlForRouteType(WPRouteType.WCCustomerInfo), + userToken: userToken, + shouldAuthRequest: true); // return response return _jsonHasBadStatus(json) @@ -350,12 +450,14 @@ class WPAppNetworkManager { /// /// Returns a [WcPointsAndRewardUser] future. /// Throws an [Exception] if fails. - Future wcPointsAndRewardsUser(String userToken) async { + Future wcPointsAndRewardsUser( + {String? userToken}) async { // send http request final json = await _http( method: "POST", url: _urlForRouteType(WPRouteType.WCPointsAndRewardsUser), userToken: userToken, + shouldAuthRequest: true, ); // return response @@ -369,14 +471,15 @@ class WPAppNetworkManager { /// Returns a [WcPointsAndRewardCalculatePoints] future. /// Throws an [Exception] if fails. Future wcPointsAndRewardsCalculatePoints( - String userToken, - {required double points}) async { + {required double points, String? userToken}) async { // send http request final json = await _http( - method: "POST", - url: _urlForRouteType(WPRouteType.WCPointsAndRewardsCalculatePoints), - userToken: userToken, - body: {"points": points}); + method: "POST", + url: _urlForRouteType(WPRouteType.WCPointsAndRewardsCalculatePoints), + userToken: userToken, + shouldAuthRequest: true, + body: {"points": points}, + ); // return response return _jsonHasBadStatus(json) @@ -389,8 +492,9 @@ class WPAppNetworkManager { /// /// Returns [WCCustomerUpdatedResponse] future. /// Throws an [Exception] if fails. - Future wcUpdateCustomerInfo(userToken, - {String? firstName, + Future wcUpdateCustomerInfo( + {String? userToken, + String? firstName, String? lastName, String? displayName, String? billingFirstName, @@ -462,11 +566,11 @@ class WPAppNetworkManager { // send http request final json = await _http( - method: "POST", - url: _urlForRouteType(WPRouteType.WCCustomerUpdateInfo), - body: payload, - userToken: userToken, - ); + method: "POST", + url: _urlForRouteType(WPRouteType.WCCustomerUpdateInfo), + body: payload, + userToken: userToken, + shouldAuthRequest: true); // return response return _jsonHasBadStatus(json) @@ -483,7 +587,8 @@ class WPAppNetworkManager { {required String method, required String url, Map? body, - String? userToken}) async { + String? userToken, + bool shouldAuthRequest = false}) async { Response? response; if (method == "GET") { response = await dio.get(url); @@ -494,6 +599,10 @@ class WPAppNetworkManager { if (body == null) { body = {}; } + String? userTokenFromStorage = await WPJsonAPI.wpUserToken(); + if (shouldAuthRequest && userTokenFromStorage != null) { + body.addAll({"token": userTokenFromStorage}); + } if (userToken != null) { body.addAll({"token": userToken}); } @@ -634,6 +743,17 @@ class WPAppNetworkManager { } } + /// Generates a random string of [length] characters. + String _randomString(int length) { + const chars = "abcdefghijklmnopqrstuvwxyz0123456789"; + math.Random rnd = math.Random(DateTime.now().millisecondsSinceEpoch); + String result = ""; + for (var i = 0; i < length; i++) { + result += chars[rnd.nextInt(chars.length)]; + } + return result; + } + /// Throws an exception from the [json] status returned from payload. _throwExceptionForStatusCode(json) { if (json != null && json['status'] != null) { diff --git a/lib/wp_json_api.dart b/lib/wp_json_api.dart index fccec70..fa0288a 100644 --- a/lib/wp_json_api.dart +++ b/lib/wp_json_api.dart @@ -15,15 +15,21 @@ library wp_json_api; -import 'package:wp_json_api/helpers/typedefs.dart'; -import 'package:wp_json_api/networking/network_manager.dart'; +import 'package:nylo_support/helpers/auth.dart'; +import 'package:nylo_support/helpers/helper.dart'; +import '/helpers/typedefs.dart'; +import '/models/wp_user.dart'; +import '/networking/network_manager.dart'; -/// The base class to initialize and use WPJSONAPI +/// The version of the wp_json_api +String _wpJsonAPIVersion = "3.5.0"; + +/// The base class to initialize and use WPJsonAPI class WPJsonAPI { - /// Private constructor for WPJSONAPI + /// Private constructor for WPJsonAPI WPJsonAPI._privateConstructor(); - /// Instance of WPJSONAPI + /// Instance of WPJsonAPI static final WPJsonAPI instance = WPJsonAPI._privateConstructor(); /// The base url for the WordPress Site e.g. https://mysitewp.com @@ -35,11 +41,14 @@ class WPJsonAPI { /// Default API root for your WordPress site String _apiPath = "/wp-json"; + /// The version + static String get version => _wpJsonAPIVersion; + /// Initialize and configure class interface. /// You can optional set [shouldDebug] == false to stop debugging /// [wpJsonPath] is the root path for accessing you sites WordPress APIs /// by default this should be "/wp-json". - initWith( + init( {required String baseUrl, String wpJsonPath = '/wp-json', bool shouldDebug = true}) { @@ -48,6 +57,54 @@ class WPJsonAPI { _setShouldDebug(value: shouldDebug); } + /// Login a user with the [WpUser] + static wpLogin(WpUser wpUser) async { + await Auth.set(wpUser, key: storageKey()); + } + + /// Logout a user + static wpLogout() async { + await Auth.remove(key: storageKey()); + } + + /// Authenticate a user if they are logged in + static wpAuth() async { + await Auth.loginModel( + WPJsonAPI.storageKey(), (data) => WpUser.fromJson(data)); + } + + /// Check if a user is logged in + static Future wpUserLoggedIn() async { + WpUser? _wpUser = await wpUser(); + if (_wpUser == null) { + return false; + } + if (_wpUser.token == null) { + return false; + } + return true; + } + + /// Returns the logged in user + static Future wpUser() async { + return await NyStorage.read(storageKey(), modelDecoders: { + WpUser: (json) => WpUser.fromJson(json), + }); + } + + /// Returns the user ID of the logged in user + static Future wpUserId() async { + WpUser? _wpUser = await wpUser(); + return _wpUser?.id.toString(); + } + + /// Get the token for the user + static Future wpUserToken() async { + WpUser? _wpUser = await wpUser(); + if (_wpUser == null) return null; + return _wpUser.token; + } + /// Sets the base API in the class _setBaseApi({required baseUrl}) { this._baseUrl = baseUrl; @@ -78,4 +135,7 @@ class WPJsonAPI { api(RequestCallback request) async { return await request(WPAppNetworkManager.instance); } + + /// Returns the storage key for the plugin + static String storageKey() => "wp_json_api"; } diff --git a/pubspec.lock b/pubspec.lock index b32c10a..233a244 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + animate_do: + dependency: transitive + description: + name: animate_do + sha256: "7a3162729f0ea042f9dd84da217c5bde5472ad9cef644079929d4304a5dc4ca0" + url: "https://pub.dev" + source: hosted + version: "3.3.4" async: dependency: transitive description: @@ -49,6 +57,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.4.1" + equatable: + dependency: transitive + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" fake_async: dependency: transitive description: @@ -57,16 +73,122 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_dotenv: + dependency: transitive + description: + name: flutter_dotenv + sha256: "9357883bdd153ab78cbf9ffa07656e336b8bbb2b5a3ca596b0b27e119f7c7d77" + url: "https://pub.dev" + source: hosted + version: "5.1.0" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + flutter_secure_storage: + dependency: transitive + description: + name: flutter_secure_storage + sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685 + url: "https://pub.dev" + source: hosted + version: "9.0.0" + flutter_secure_storage_linux: + dependency: transitive + description: + name: flutter_secure_storage_linux + sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + flutter_secure_storage_macos: + dependency: transitive + description: + name: flutter_secure_storage_macos + sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c + url: "https://pub.dev" + source: hosted + version: "3.0.1" + flutter_secure_storage_platform_interface: + dependency: transitive + description: + name: flutter_secure_storage_platform_interface + sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + flutter_secure_storage_web: + dependency: transitive + description: + name: flutter_secure_storage_web + sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_secure_storage_windows: + dependency: transitive + description: + name: flutter_secure_storage_windows + sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + flutter_staggered_grid_view: + dependency: transitive + description: + name: flutter_staggered_grid_view + sha256: "19e7abb550c96fbfeb546b23f3ff356ee7c59a019a651f8f102a4ba9b7349395" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + flutter_styled_toast: + dependency: transitive + description: + name: flutter_styled_toast + sha256: e667f13a665820eb0fa8506547e47eacbcddf1948d6d3036cfd3b089bd4b0516 + url: "https://pub.dev" + source: hosted + version: "2.2.1" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + get_time_ago: + dependency: transitive + description: + name: get_time_ago + sha256: "982d1b82c7b2cbb8f443cee5db9508e6c8efb7f7be5b659f17d3575c340d09d3" + url: "https://pub.dev" + source: hosted + version: "1.3.1" http_parser: dependency: transitive description: @@ -75,6 +197,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + intl: + dependency: transitive + description: + name: intl + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + url: "https://pub.dev" + source: hosted + version: "0.18.1" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" leak_tracker: dependency: transitive description: @@ -123,6 +261,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.11.0" + nylo_support: + dependency: "direct main" + description: + name: nylo_support + sha256: "2927b62a1dfbed8e85847e9460d0b8bcca3ec61b4d72318f3835dbbad6980fb0" + url: "https://pub.dev" + source: hosted + version: "5.56.1" + page_transition: + dependency: transitive + description: + name: page_transition + sha256: dee976b1f23de9bbef5cd512fe567e9f6278caee11f5eaca9a2115c19dc49ef6 + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: @@ -131,6 +285,166 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.0" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + platform: + dependency: transitive + description: + name: platform + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + url: "https://pub.dev" + source: hosted + version: "3.1.4" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pretty_dio_logger: + dependency: transitive + description: + name: pretty_dio_logger + sha256: "00b80053063935cf9a6190da344c5373b9d0e92da4c944c878ff2fbef0ef6dc2" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + pull_to_refresh_flutter3: + dependency: transitive + description: + name: pull_to_refresh_flutter3 + sha256: "37a88d901cca9a46dbdd46523de8e7b35a3e58634a0e775b1a5904981f69b353" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + recase: + dependency: transitive + description: + name: recase + sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 + url: "https://pub.dev" + source: hosted + version: "4.1.0" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + url: "https://pub.dev" + source: hosted + version: "0.27.7" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" + url: "https://pub.dev" + source: hosted + version: "2.3.5" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" + url: "https://pub.dev" + source: hosted + version: "2.3.0" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + skeletonizer: + dependency: transitive + description: + name: skeletonizer + sha256: "2eb80153c80507359ff05f6a18ed50ae0bafa1b999aa867a8cef0a53387b5650" + url: "https://pub.dev" + source: hosted + version: "1.1.0" sky_engine: dependency: transitive description: flutter @@ -184,6 +498,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.1" + theme_provider: + dependency: transitive + description: + name: theme_provider + sha256: "6a2839ee1bd539ceb789f25ea9696fe90f9dfad28e3228f209b8ff9255c58099" + url: "https://pub.dev" + source: hosted + version: "0.6.0" typed_data: dependency: transitive description: @@ -192,6 +514,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + validated: + dependency: transitive + description: + name: validated + sha256: f4da18b50fa2aeda8d2f6e55bdf73759593abe3f9dd4aeece4e98bf3438e6a9f + url: "https://pub.dev" + source: hosted + version: "2.0.0" vector_math: dependency: transitive description: @@ -208,6 +538,30 @@ packages: url: "https://pub.dev" source: hosted version: "13.0.0" + web: + dependency: transitive + description: + name: web + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + url: "https://pub.dev" + source: hosted + version: "0.5.1" + win32: + dependency: transitive + description: + name: win32 + sha256: "8cb58b45c47dcb42ab3651533626161d6b67a2921917d8d429791f76972b3480" + url: "https://pub.dev" + source: hosted + version: "5.3.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + url: "https://pub.dev" + source: hosted + version: "1.0.4" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=1.17.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index bb159cb..d8ad411 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: wp_json_api description: WordPress and WooCommerce JSON API for Flutter Mobile. API allows you to login, register new users, get users info and more. -version: 3.4.0 +version: 3.5.0 homepage: https://woosignal.com repository: https://github.com/woosignal/wp-json-api-flutter issue_tracker: https://github.com/woosignal/wp-json-api-flutter/issues @@ -12,6 +12,7 @@ environment: dependencies: dio: ^5.4.1 + nylo_support: ^5.56.1 flutter: sdk: flutter collection: ^1.17.0