@fleetbase/storefront-engine 0.3.27 → 0.3.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/composer.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbase/storefront-api",
3
- "version": "0.3.27",
3
+ "version": "0.3.29",
4
4
  "description": "Headless Commerce & Marketplace Extension for Fleetbase",
5
5
  "keywords": [
6
6
  "fleetbase-extension",
package/extension.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Storefront",
3
- "version": "0.3.27",
3
+ "version": "0.3.29",
4
4
  "description": "Headless Commerce & Marketplace Extension for Fleetbase",
5
5
  "repository": "https://github.com/fleetbase/storefront",
6
6
  "license": "AGPL-3.0-or-later",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/storefront-engine",
3
- "version": "0.3.27",
3
+ "version": "0.3.29",
4
4
  "description": "Headless Commerce & Marketplace Extension for Fleetbase",
5
5
  "fleetbase": {
6
6
  "route": "storefront",
@@ -43,14 +43,14 @@
43
43
  "publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish"
44
44
  },
45
45
  "dependencies": {
46
+ "@babel/core": "^7.23.2",
46
47
  "@fleetbase/ember-core": "latest",
47
48
  "@fleetbase/ember-ui": "latest",
48
49
  "@fleetbase/fleetops-data": "latest",
49
- "@babel/core": "^7.23.2",
50
50
  "@fortawesome/ember-fontawesome": "^2.0.0",
51
51
  "@fortawesome/fontawesome-svg-core": "6.4.0",
52
- "@fortawesome/free-solid-svg-icons": "6.4.0",
53
52
  "@fortawesome/free-brands-svg-icons": "6.4.0",
53
+ "@fortawesome/free-solid-svg-icons": "6.4.0",
54
54
  "ember-auto-import": "^2.7.4",
55
55
  "ember-cli-babel": "^8.2.0",
56
56
  "ember-cli-htmlbars": "^6.3.0",
@@ -59,12 +59,12 @@
59
59
  "ember-wormhole": "^0.6.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@fleetbase/intl-lint": "^0.0.1",
63
62
  "@babel/eslint-parser": "^7.22.15",
64
63
  "@babel/plugin-proposal-decorators": "^7.23.2",
65
64
  "@ember/optional-features": "^2.0.0",
66
65
  "@ember/test-helpers": "^3.2.0",
67
66
  "@embroider/test-setup": "^3.0.2",
67
+ "@fleetbase/intl-lint": "^0.0.1",
68
68
  "@glimmer/component": "^1.1.2",
69
69
  "@glimmer/tracking": "^1.1.2",
70
70
  "broccoli-asset-rev": "^3.0.0",
@@ -13,6 +13,7 @@ use Fleetbase\FleetOps\Models\Contact;
13
13
  use Fleetbase\FleetOps\Models\Order;
14
14
  use Fleetbase\FleetOps\Models\Place;
15
15
  use Fleetbase\Http\Controllers\Controller;
16
+ use Fleetbase\Models\File;
16
17
  use Fleetbase\Models\User;
17
18
  use Fleetbase\Models\UserDevice;
18
19
  use Fleetbase\Models\VerificationCode;
@@ -176,8 +177,8 @@ class CustomerController extends Controller
176
177
  }
177
178
 
178
179
  // verify code
179
- $isVerified = VerificationCode::where(['code' => $code, 'for' => 'storefront_create_customer', 'meta->identity' => $identity])->exists();
180
- if (!$isVerified) {
180
+ $verificationCode = VerificationCode::where(['code' => $code, 'for' => 'storefront_create_customer', 'meta->identity' => $identity])->exists();
181
+ if (!$verificationCode) {
181
182
  return response()->apiError('Invalid verification code provided!');
182
183
  }
183
184
 
@@ -210,6 +211,27 @@ class CustomerController extends Controller
210
211
  'origin' => 'storefront',
211
212
  ];
212
213
 
214
+ // Handle photo as either file id/ or base64 data string
215
+ $photo = $request->input('photo');
216
+ if ($photo) {
217
+ // Handle photo being a file id
218
+ if (Utils::isPublicId($photo)) {
219
+ $file = File::where('public_id', $photo)->first();
220
+ if ($file) {
221
+ $input['photo_uuid'] = $file->uuid;
222
+ }
223
+ }
224
+
225
+ // Handle the photo being base64 data string
226
+ if (Utils::isBase64String($photo)) {
227
+ $path = implode('/', ['uploads', session('company'), 'customers']);
228
+ $file = File::createFromBase64($photo, null, $path);
229
+ if ($file) {
230
+ $input['photo_uuid'] = $file->uuid;
231
+ }
232
+ }
233
+ }
234
+
213
235
  // create the customer/contact
214
236
  try {
215
237
  $customer = Contact::create($input);
@@ -269,6 +291,32 @@ class CustomerController extends Controller
269
291
  ]);
270
292
  }
271
293
 
294
+ // Handle photo as either file id/ or base64 data string
295
+ $photo = $request->input('photo');
296
+ if ($photo) {
297
+ // Handle photo being a file id
298
+ if (Utils::isPublicId($photo)) {
299
+ $file = File::where('public_id', $photo)->first();
300
+ if ($file) {
301
+ $input['photo_uuid'] = $file->uuid;
302
+ }
303
+ }
304
+
305
+ // Handle the photo being base64 data string
306
+ if (Utils::isBase64String($photo)) {
307
+ $path = implode('/', ['uploads', session('company'), 'customers']);
308
+ $file = File::createFromBase64($photo, null, $path);
309
+ if ($file) {
310
+ $input['photo_uuid'] = $file->uuid;
311
+ }
312
+ }
313
+
314
+ // Handle removal key
315
+ if ($photo === 'REMOVE') {
316
+ $input['photo_uuid'] = null;
317
+ }
318
+ }
319
+
272
320
  // update the contact
273
321
  try {
274
322
  $contact->update($input);
@@ -802,4 +850,99 @@ class CustomerController extends Controller
802
850
  return response()->apiError($e->getMessage());
803
851
  }
804
852
  }
853
+
854
+ public function startAccountClosure(Request $request)
855
+ {
856
+ $about = Storefront::about(['company_uuid']);
857
+ if (!$about) {
858
+ return response()->apiError('Storefront not found.');
859
+ }
860
+
861
+ $customer = Storefront::getCustomerFromToken();
862
+ if (!$customer) {
863
+ return response()->apiError('Not authorized to view customers places');
864
+ }
865
+
866
+ // Get the user account for the contact/customer
867
+ $user = User::where(['uuid' => $customer->user_uuid])->first();
868
+ if (!$user) {
869
+ return response()->apiError('Customer user account not found.');
870
+ }
871
+
872
+ // Check for phone or email
873
+ if (!$user->phone && !$user->email) {
874
+ return response()->apiError('Customer account must have a valid email or phone number linked.');
875
+ }
876
+
877
+ // Send account closure confirmation with code
878
+ try {
879
+ if ($user->phone) {
880
+ VerificationCode::generateSmsVerificationFor($user, 'storefront_account_closure', [
881
+ 'messageCallback' => function ($verification) use ($about) {
882
+ return "Your {$about->name} account closure verification code is {$verification->code}";
883
+ },
884
+ 'meta' => ['identity' => $user->phone],
885
+ ]);
886
+ } elseif ($user->email) {
887
+ VerificationCode::generateEmailVerificationFor($user, 'storefront_account_closure', [
888
+ 'subject' => $about->name . ' account closure request',
889
+ 'messageCallback' => function ($verification) use ($about) {
890
+ return "Your {$about->name} account closure verification code is {$verification->code}";
891
+ },
892
+ 'meta' => ['identity' => $user->email],
893
+ ]);
894
+ }
895
+
896
+ return response()->json(['status' => 'OK']);
897
+ } catch (\Exception $e) {
898
+ return response()->apiError($e->getMessage());
899
+ }
900
+
901
+ return response()->apiError('An uknown error occured attempting to close customer account.');
902
+ }
903
+
904
+ public function confirmAccountClosure(Request $request)
905
+ {
906
+ $code = $request->input('code');
907
+ $about = Storefront::about(['company_uuid']);
908
+ if (!$about) {
909
+ return response()->apiError('Storefront not found.');
910
+ }
911
+
912
+ $customer = Storefront::getCustomerFromToken();
913
+ if (!$customer) {
914
+ return response()->apiError('Not authorized to view customers places');
915
+ }
916
+
917
+ // Get the user account for the contact/customer
918
+ $user = User::where(['uuid' => $customer->user_uuid])->first();
919
+ if (!$user) {
920
+ return response()->apiError('Customer user account not found.');
921
+ }
922
+
923
+ // Get verification identity
924
+ $identity = $user->phone ?? $user->email;
925
+
926
+ // verify account closure code
927
+ $verificationCode = VerificationCode::where(['code' => $code, 'for' => 'storefront_account_closure', 'meta->identity' => $identity])->exists();
928
+ if (!$verificationCode && $code !== config('storefront.storefront_app.bypass_verification_code')) {
929
+ return response()->apiError('Invalid verification code provided!');
930
+ }
931
+
932
+ try {
933
+ // If the user type is `contact` or `customer` delete the user account
934
+ if ($user->isType(['contact', 'customer'])) {
935
+ $user->delete();
936
+ }
937
+
938
+ // Delete the customer
939
+ $customer->delete();
940
+
941
+ return response()->json(['status' => 'OK']);
942
+ } catch (\Exception $e) {
943
+ return response()->apiError($e->getMessage());
944
+ }
945
+
946
+ return response()->apiError('An uknown error occured attempting to close customer account.');
947
+ }
805
948
  }
@@ -52,7 +52,7 @@ class PushNotification
52
52
  );
53
53
 
54
54
  return (new FcmMessage(notification: $notification))
55
- ->setData(['order' => $order->uuid, 'id' => $order->public_id, 'type' => $status])
55
+ ->data(['order' => $order->uuid, 'id' => $order->public_id, 'type' => $status])
56
56
  ->custom([
57
57
  'android' => [
58
58
  'notification' => [
@@ -113,6 +113,8 @@ Route::prefix(config('storefront.api.routing.prefix', 'storefront'))->namespace(
113
113
  $router->post('request-creation-code', 'CustomerController@requestCustomerCreationCode');
114
114
  $router->post('stripe-ephemeral-key', 'CustomerController@getStripeEphemeralKey');
115
115
  $router->post('stripe-setup-intent', 'CustomerController@getStripeSetupIntent');
116
+ $router->post('account-closure', 'CustomerController@startAccountClosure');
117
+ $router->post('confirm-account-closure', 'CustomerController@confirmAccountClosure');
116
118
  });
117
119
 
118
120
  // hotfix! storefront-app sending customer update to /contacts/ route