@revenexx/cover 0.1.0
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/LICENSE +21 -0
- package/README.md +39 -0
- package/app/api/account.ts +8 -0
- package/app/api/categories.ts +3 -0
- package/app/api/checkout.ts +6 -0
- package/app/api/images.ts +4 -0
- package/app/api/markets.ts +3 -0
- package/app/api/product.ts +3 -0
- package/app/api/products.ts +4 -0
- package/app/api/search.ts +4 -0
- package/app/app.config.ts +29 -0
- package/app/assets/css/cover.css +25 -0
- package/app/components/account/AccountMenu.vue +30 -0
- package/app/components/account/AccountShell.vue +18 -0
- package/app/components/account/AccountSidebar.vue +90 -0
- package/app/components/account/address/AccountAddressCard.vue +287 -0
- package/app/components/account/carts/AccountCartsTable.vue +284 -0
- package/app/components/account/dashboard/AccountDashboard.vue +351 -0
- package/app/components/account/directorder/AccountDirectOrder.vue +512 -0
- package/app/components/account/governance/AccountApprovalLimitsTable.vue +221 -0
- package/app/components/account/governance/AccountCostCenterDetail.vue +276 -0
- package/app/components/account/governance/AccountCostCentersTable.vue +252 -0
- package/app/components/account/governance/AccountRequisitionDetail.vue +295 -0
- package/app/components/account/governance/AccountRequisitionsTable.vue +255 -0
- package/app/components/account/governance/AccountWorkflowDetail.vue +215 -0
- package/app/components/account/governance/AccountWorkflowsTable.vue +168 -0
- package/app/components/account/governance/GovernanceApprovalLimitModal.vue +183 -0
- package/app/components/account/governance/GovernanceCostCenterModal.vue +188 -0
- package/app/components/account/governance/GovernanceWorkflowModal.vue +191 -0
- package/app/components/account/orderlists/AccountOrderListDetail.vue +349 -0
- package/app/components/account/orderlists/AccountOrderListsTable.vue +352 -0
- package/app/components/account/orders/AccountOrderDetail.vue +376 -0
- package/app/components/account/orders/AccountOrdersTable.vue +281 -0
- package/app/components/account/preferences/AccountPreferences.vue +50 -0
- package/app/components/auth/AuthForgotPasswordPanel.vue +88 -0
- package/app/components/auth/AuthLoginPanel.vue +103 -0
- package/app/components/auth/AuthLoginTeaser.vue +24 -0
- package/app/components/auth/AuthPageHeader.vue +21 -0
- package/app/components/auth/AuthRegisterPanel.vue +431 -0
- package/app/components/auth/AuthRegisterTeaser.vue +24 -0
- package/app/components/auth/AuthResetPasswordPanel.vue +115 -0
- package/app/components/cart/CartButton.vue +42 -0
- package/app/components/cart/actions/CartCostCenterModal.vue +110 -0
- package/app/components/cart/actions/CartExportModal.vue +82 -0
- package/app/components/cart/actions/CartPositionTextsModal.vue +92 -0
- package/app/components/cart/actions/CartSaveToListModal.vue +177 -0
- package/app/components/cart/actions/CartWorkflowPickerModal.vue +64 -0
- package/app/components/cart/drawer/CartDrawer.vue +49 -0
- package/app/components/cart/item/CartItem.vue +318 -0
- package/app/components/cart/manage/CartNameModal.vue +68 -0
- package/app/components/cart/position/CartPosition.vue +369 -0
- package/app/components/cart/quickadd/CartQuickAdd.vue +145 -0
- package/app/components/cart/recommend/CartCrossSell.vue +102 -0
- package/app/components/cart/recommend/CartRecommendCard.vue +59 -0
- package/app/components/cart/recommend/CartReorderStrip.vue +108 -0
- package/app/components/cart/requisition/CartRequisitionGroup.vue +74 -0
- package/app/components/cart/skeleton/CartSkeleton.vue +18 -0
- package/app/components/cart/summary/CartSummary.vue +25 -0
- package/app/components/cart/summary/CartSummaryBreakdown.vue +35 -0
- package/app/components/cart/switcher/CartSwitcher.vue +147 -0
- package/app/components/cart/target/CartTargetModal.vue +129 -0
- package/app/components/cart/view/CartApprovalsPanel.vue +89 -0
- package/app/components/cart/view/CartListHeader.vue +86 -0
- package/app/components/cart/view/CartPositionList.vue +94 -0
- package/app/components/cart/view/CartSummaryPanel.vue +254 -0
- package/app/components/cart/view/CartView.vue +310 -0
- package/app/components/category/info/CategoryPrice.vue +47 -0
- package/app/components/category/info/CategorySku.vue +15 -0
- package/app/components/category/info/CategoryStock.vue +25 -0
- package/app/components/category/list/CategoryItemCount.vue +27 -0
- package/app/components/category/list/CategoryListPagination.vue +81 -0
- package/app/components/category/skeleton/CategoryDetailSkeleton.vue +12 -0
- package/app/components/category/skeleton/CategoryListSkeleton.vue +65 -0
- package/app/components/category/view/CategoryViewToggle.vue +33 -0
- package/app/components/category/view/GridView.vue +78 -0
- package/app/components/category/view/ListView.vue +80 -0
- package/app/components/checkout/confirmation/CheckoutConfirmationView.vue +289 -0
- package/app/components/checkout/form/CheckoutSchemaForm.vue +72 -0
- package/app/components/checkout/onepage/CheckoutAddressPickerModal.vue +260 -0
- package/app/components/checkout/onepage/CheckoutAddressSection.vue +186 -0
- package/app/components/checkout/onepage/CheckoutDeliverySection.vue +158 -0
- package/app/components/checkout/onepage/CheckoutGate.vue +67 -0
- package/app/components/checkout/onepage/CheckoutGuestDetailsSection.vue +154 -0
- package/app/components/checkout/onepage/CheckoutNotesSection.vue +62 -0
- package/app/components/checkout/onepage/CheckoutOnePageView.vue +77 -0
- package/app/components/checkout/onepage/CheckoutPaymentSection.vue +181 -0
- package/app/components/checkout/onepage/CheckoutSectionTitle.vue +18 -0
- package/app/components/checkout/onepage/CheckoutSummarySection.vue +211 -0
- package/app/components/checkout/onepage/CheckoutWorkflowPanel.vue +38 -0
- package/app/components/layout/AppLogo.vue +21 -0
- package/app/components/layout/footer/Footer.vue +148 -0
- package/app/components/layout/header/AppBar.vue +75 -0
- package/app/components/layout/header/CategoryNav.vue +93 -0
- package/app/components/layout/header/HeaderActionItem.vue +81 -0
- package/app/components/layout/header/LocaleSwitcher.vue +123 -0
- package/app/components/layout/header/MainNav.vue +61 -0
- package/app/components/layout/header/MobileMenu.vue +81 -0
- package/app/components/layout/header/TopBar.vue +63 -0
- package/app/components/listing/ListingView.vue +227 -0
- package/app/components/product/detail/ProductDetailAddToCart.vue +188 -0
- package/app/components/product/detail/ProductDetailDescription.vue +20 -0
- package/app/components/product/detail/ProductDetailImageGallery.vue +58 -0
- package/app/components/product/detail/ProductDetailPricing.vue +108 -0
- package/app/components/product/detail/ProductDetailSaveToList.vue +291 -0
- package/app/components/product/detail/ProductDetailSpecifications.vue +33 -0
- package/app/components/product/detail/ProductDetailStock.vue +36 -0
- package/app/components/search/filter/SearchFacets.vue +256 -0
- package/app/components/search/filter/SearchFacetsDrawer.vue +58 -0
- package/app/components/ui/AppShell.vue +7 -0
- package/app/components/ui/debug/PiniaStateCard.vue +106 -0
- package/app/components/ui/feedback/EmptyState.vue +30 -0
- package/app/components/ui/feedback/ErrorBoundary.vue +44 -0
- package/app/components/ui/feedback/NotFound.vue +34 -0
- package/app/components/ui/forms/CountrySelection.vue +14 -0
- package/app/components/ui/forms/FormKitDatePicker.vue +124 -0
- package/app/components/ui/forms/PasswordInput.vue +136 -0
- package/app/components/ui/forms/SearchInput.vue +213 -0
- package/app/components/ui/table/TableSortButton.vue +51 -0
- package/app/components/ui/table/TableToolbar.vue +66 -0
- package/app/composables/useAccount.ts +27 -0
- package/app/composables/useAccountAddresses.ts +116 -0
- package/app/composables/useAccountOrders.ts +18 -0
- package/app/composables/useAppUrl.ts +38 -0
- package/app/composables/useAuthStore.ts +202 -0
- package/app/composables/useB2BContext.ts +23 -0
- package/app/composables/useCartActions.ts +25 -0
- package/app/composables/useCartCalculation.ts +90 -0
- package/app/composables/useCartSelection.ts +46 -0
- package/app/composables/useCartStore.ts +837 -0
- package/app/composables/useCartSummaryFormatting.ts +28 -0
- package/app/composables/useCategories.ts +29 -0
- package/app/composables/useCheckoutOnePage.ts +438 -0
- package/app/composables/useCheckoutProfileSource.ts +8 -0
- package/app/composables/useCheckoutSchema.ts +28 -0
- package/app/composables/useDataTable.ts +14 -0
- package/app/composables/useFormValidation.ts +29 -0
- package/app/composables/useIcons.ts +17 -0
- package/app/composables/useLocalePreferences.ts +45 -0
- package/app/composables/useMarkets.ts +15 -0
- package/app/composables/useProduct.ts +89 -0
- package/app/composables/useProductCard.ts +8 -0
- package/app/composables/useProductCardActions.ts +106 -0
- package/app/composables/useProductImage.ts +12 -0
- package/app/composables/useProductListing.ts +210 -0
- package/app/composables/useProductUrl.ts +17 -0
- package/app/composables/useProducts.ts +130 -0
- package/app/composables/useSearch.ts +12 -0
- package/app/composables/useThemeStore.ts +81 -0
- package/app/composables/useViewMode.ts +18 -0
- package/app/config/countries.ts +74 -0
- package/app/config/icons.ts +283 -0
- package/app/config/navigation.ts +191 -0
- package/app/config/palette.ts +13 -0
- package/app/config/themes.ts +20 -0
- package/app/formkit.config.ts +50 -0
- package/app/interfaces/account/address-list.ts +34 -0
- package/app/interfaces/account/order-list.ts +47 -0
- package/app/interfaces/account/order-lists.ts +35 -0
- package/app/interfaces/account/profile.ts +17 -0
- package/app/interfaces/account.ts +3 -0
- package/app/interfaces/address.ts +9 -0
- package/app/interfaces/auth.ts +104 -0
- package/app/interfaces/b2b.ts +234 -0
- package/app/interfaces/cart-calculation.ts +131 -0
- package/app/interfaces/cart-item.ts +45 -0
- package/app/interfaces/checkout-draft.ts +4 -0
- package/app/interfaces/checkout.ts +43 -0
- package/app/interfaces/delivery.ts +13 -0
- package/app/interfaces/market.ts +24 -0
- package/app/interfaces/payment.ts +19 -0
- package/app/interfaces/persisted-cart.ts +10 -0
- package/app/interfaces/product-detail.ts +54 -0
- package/app/interfaces/product-list.ts +33 -0
- package/app/interfaces/search-facets.ts +14 -0
- package/app/interfaces/validation.ts +14 -0
- package/app/layouts/default.vue +78 -0
- package/app/layouts/focus.vue +80 -0
- package/app/plugins/formkit-locale.client.ts +23 -0
- package/app/shared/constants.ts +1 -0
- package/app/validations/companyName.ts +18 -0
- package/app/validations/emailFormat.ts +10 -0
- package/app/validations/formValidationConfig.ts +50 -0
- package/app/validations/maxLength.ts +12 -0
- package/app/validations/minLength.ts +9 -0
- package/app/validations/optionalCompanyName.ts +23 -0
- package/app/validations/passwordsMatch.ts +5 -0
- package/app/validations/phoneNumber.ts +19 -0
- package/app/validations/required.ts +11 -0
- package/app/validations/termsRequired.ts +4 -0
- package/app/validations/types.ts +10 -0
- package/app/validations/zipCode.ts +15 -0
- package/i18n/locales/de/account.json +458 -0
- package/i18n/locales/de/auth.json +155 -0
- package/i18n/locales/de/cart.json +263 -0
- package/i18n/locales/de/checkout.json +217 -0
- package/i18n/locales/de/common.json +80 -0
- package/i18n/locales/de/cover.json +33 -0
- package/i18n/locales/de/order.json +1 -0
- package/i18n/locales/de/product.json +71 -0
- package/i18n/locales/de/search.json +54 -0
- package/i18n/locales/de/validation.json +12 -0
- package/i18n/locales/en/account.json +458 -0
- package/i18n/locales/en/auth.json +155 -0
- package/i18n/locales/en/cart.json +263 -0
- package/i18n/locales/en/checkout.json +217 -0
- package/i18n/locales/en/common.json +80 -0
- package/i18n/locales/en/cover.json +33 -0
- package/i18n/locales/en/order.json +1 -0
- package/i18n/locales/en/product.json +71 -0
- package/i18n/locales/en/search.json +54 -0
- package/i18n/locales/en/validation.json +12 -0
- package/nuxt.config.ts +109 -0
- package/package.json +65 -0
- package/public/img/product-placeholder.svg +8 -0
- package/public/templates/direct-order-template.csv +3 -0
- package/public/templates/direct-order-template.xlsx +0 -0
- package/server/api/account/address/[id].delete.ts +51 -0
- package/server/api/account/address/[id].put.ts +83 -0
- package/server/api/account/address/index.post.ts +60 -0
- package/server/api/account/addresses.get.ts +25 -0
- package/server/api/account/context.get.ts +16 -0
- package/server/api/account/governance/[domain]/[id].put.ts +57 -0
- package/server/api/account/governance/[domain].post.ts +111 -0
- package/server/api/account/order-lists/[id].delete.ts +22 -0
- package/server/api/account/order-lists/[id].get.ts +17 -0
- package/server/api/account/order-lists/[id].put.ts +46 -0
- package/server/api/account/order-lists/index.get.ts +14 -0
- package/server/api/account/order-lists/index.post.ts +38 -0
- package/server/api/account/orders/[id].get.ts +35 -0
- package/server/api/account/orders.get.ts +35 -0
- package/server/api/account/profile.get.ts +56 -0
- package/server/api/account/profile.put.ts +128 -0
- package/server/api/account/requisitions/[id].get.ts +15 -0
- package/server/api/account/requisitions.get.ts +23 -0
- package/server/api/auth/login.post.ts +37 -0
- package/server/api/auth/logout.post.ts +4 -0
- package/server/api/auth/me.get.ts +3 -0
- package/server/api/auth/personas.get.ts +7 -0
- package/server/api/auth/recovery.post.ts +32 -0
- package/server/api/auth/recovery.put.ts +37 -0
- package/server/api/auth/register.post.ts +126 -0
- package/server/api/cart/calculate.post.ts +25 -0
- package/server/api/cart/export.post.ts +81 -0
- package/server/api/cart/index.delete.ts +10 -0
- package/server/api/cart/index.get.ts +10 -0
- package/server/api/cart/sync.post.ts +14 -0
- package/server/api/carts/[id]/activate.post.ts +18 -0
- package/server/api/carts/[id]/index.delete.ts +18 -0
- package/server/api/carts/[id]/index.put.ts +19 -0
- package/server/api/carts/[id]/items.post.ts +21 -0
- package/server/api/carts/index.get.ts +14 -0
- package/server/api/carts/index.post.ts +14 -0
- package/server/api/categories/[slug].get.ts +22 -0
- package/server/api/categories/index.get.ts +11 -0
- package/server/api/checkout/profile.get.ts +21 -0
- package/server/api/checkout/schema/[key].get.ts +19 -0
- package/server/api/checkout/session.post.ts +8 -0
- package/server/api/images/detail/[filename].get.ts +18 -0
- package/server/api/images/list/[filename].get.ts +17 -0
- package/server/api/markets.get.ts +9 -0
- package/server/api/orders/index.post.ts +376 -0
- package/server/api/payment/methods.post.ts +65 -0
- package/server/api/product/[id].get.ts +29 -0
- package/server/api/products/[id].get.ts +30 -0
- package/server/api/products/index.get.ts +21 -0
- package/server/api/requisitions/index.post.ts +67 -0
- package/server/api/shipping/rates.post.ts +70 -0
- package/server/api/themes/index.get.ts +9 -0
- package/server/api/typesense/drop.get.ts +22 -0
- package/server/api/typesense/health.get.ts +9 -0
- package/server/api/typesense/search.post.ts +199 -0
- package/server/api/typesense/seed.get.ts +112 -0
- package/server/api/typesense/suggest.post.ts +69 -0
- package/server/config/account/organization.json +146 -0
- package/server/config/account/personas.json +169 -0
- package/server/config/account/user.json +8 -0
- package/server/config/account/workflows.json +19 -0
- package/server/data/account/address-list.json +103 -0
- package/server/data/account/order-list.json +491 -0
- package/server/data/account/order-lists.json +149 -0
- package/server/data/account/profile.json +9 -0
- package/server/data/account/registration-requests.json +3 -0
- package/server/data/account/requisitions.json +686 -0
- package/server/data/categories.json +186 -0
- package/server/data/forms/checkout/add-address.json +24 -0
- package/server/data/list/5137-1.png +0 -0
- package/server/data/list/5498-1.png +0 -0
- package/server/data/list/5498-2.png +0 -0
- package/server/data/list/5498-3.png +0 -0
- package/server/data/list/5498-4.png +0 -0
- package/server/data/list/5498-5.png +0 -0
- package/server/data/list/5498-6.png +0 -0
- package/server/data/list/5519-1.png +0 -0
- package/server/data/list/5713-1.png +0 -0
- package/server/data/list/5789-1.png +0 -0
- package/server/data/list/5930-1.png +0 -0
- package/server/data/list/6127-1.png +0 -0
- package/server/data/list/6234-1.png +0 -0
- package/server/data/list/6238-1.png +0 -0
- package/server/data/list/6246-1.png +0 -0
- package/server/data/list/6270-1.png +0 -0
- package/server/data/list/6330-1.png +0 -0
- package/server/data/list/6336-1.png +0 -0
- package/server/data/list/6360-1.png +0 -0
- package/server/data/list/6363-1.png +0 -0
- package/server/data/list/6375-1.png +0 -0
- package/server/data/list/6385-1.png +0 -0
- package/server/data/list/6413-1.png +0 -0
- package/server/data/list/6418-1.png +0 -0
- package/server/data/list/6465-1.png +0 -0
- package/server/data/list/6477-1.png +0 -0
- package/server/data/list/6509-1.png +0 -0
- package/server/data/list/6545-1.png +0 -0
- package/server/data/list/6548-1.png +0 -0
- package/server/data/list/6566-1.png +0 -0
- package/server/data/list/6581-1.png +0 -0
- package/server/data/list/6609-1.png +0 -0
- package/server/data/list/6611-1.png +0 -0
- package/server/data/list/6641-1.png +0 -0
- package/server/data/list/6659-1.png +0 -0
- package/server/data/list/6662-1.png +0 -0
- package/server/data/list/6689-1.png +0 -0
- package/server/data/list/6698-1.png +0 -0
- package/server/data/list/6701-1.png +0 -0
- package/server/data/list/6752-1.png +0 -0
- package/server/data/list/6755-1.png +0 -0
- package/server/data/list/6837-1.png +0 -0
- package/server/data/list/6841-1.png +0 -0
- package/server/data/list/6844-1.png +0 -0
- package/server/data/list/6846-1.png +0 -0
- package/server/data/list/6886-1.png +0 -0
- package/server/data/list/6895-1.png +0 -0
- package/server/data/list/6897-1.png +0 -0
- package/server/data/list/6919-1.png +0 -0
- package/server/data/list/6977-1.png +0 -0
- package/server/data/list/6983-1.png +0 -0
- package/server/data/list/6984-1.png +0 -0
- package/server/data/list/6985-1.png +0 -0
- package/server/data/list/6986-1.png +0 -0
- package/server/data/list/6989-1.png +0 -0
- package/server/data/list/6995-1.png +0 -0
- package/server/data/list/6998-1.png +0 -0
- package/server/data/markets.json +24 -0
- package/server/data/product-detail.json +2450 -0
- package/server/data/product-list.json +2450 -0
- package/server/data/themes.json +8 -0
- package/server/interfaces/account.ts +20 -0
- package/server/interfaces/auth.ts +32 -0
- package/server/interfaces/b2bContext.ts +23 -0
- package/server/interfaces/cart.ts +46 -0
- package/server/interfaces/cartCalculation.ts +17 -0
- package/server/interfaces/category.ts +12 -0
- package/server/interfaces/checkoutProfile.ts +5 -0
- package/server/interfaces/log.ts +3 -0
- package/server/interfaces/market.ts +10 -0
- package/server/interfaces/product.ts +21 -0
- package/server/interfaces/schema.ts +20 -0
- package/server/interfaces/theme.ts +10 -0
- package/server/services/ApiAuthService.ts +138 -0
- package/server/services/ApiCartService.ts +254 -0
- package/server/services/ApiCategoryService.ts +25 -0
- package/server/services/ApiMarketService.ts +71 -0
- package/server/services/ApiProductService.ts +53 -0
- package/server/services/LocalFileCategoryService.ts +23 -0
- package/server/services/LocalFileCheckoutProfileService.ts +117 -0
- package/server/services/LocalFileProductService.ts +128 -0
- package/server/services/LocalFileSchemaService.ts +70 -0
- package/server/services/LocalFileThemeService.ts +18 -0
- package/server/services/LogService.ts +28 -0
- package/server/services/MockAccountService.ts +58 -0
- package/server/services/MockAuthService.ts +105 -0
- package/server/services/MockB2BContextService.ts +149 -0
- package/server/services/MockCartCalculationService.ts +395 -0
- package/server/services/MockMarketService.ts +18 -0
- package/server/services/SdkAccountService.ts +56 -0
- package/server/services/SdkAuthService.ts +83 -0
- package/server/services/SessionCartService.ts +31 -0
- package/server/utils/accountService.ts +30 -0
- package/server/utils/authCookie.ts +13 -0
- package/server/utils/authService.ts +43 -0
- package/server/utils/b2bService.ts +49 -0
- package/server/utils/cartService.ts +59 -0
- package/server/utils/categoryService.ts +19 -0
- package/server/utils/checkoutProfileService.ts +9 -0
- package/server/utils/checkoutSession.ts +38 -0
- package/server/utils/coverData.ts +84 -0
- package/server/utils/governanceStore.ts +38 -0
- package/server/utils/i18n.ts +76 -0
- package/server/utils/inventoryService.ts +14 -0
- package/server/utils/liveCatalog.ts +234 -0
- package/server/utils/liveInventories.ts +76 -0
- package/server/utils/liveOrders.ts +139 -0
- package/server/utils/livePrices.ts +93 -0
- package/server/utils/locale.ts +39 -0
- package/server/utils/logService.ts +19 -0
- package/server/utils/marketService.ts +24 -0
- package/server/utils/orderService.ts +14 -0
- package/server/utils/paymentService.ts +14 -0
- package/server/utils/priceService.ts +14 -0
- package/server/utils/productService.ts +28 -0
- package/server/utils/productsSchema.ts +30 -0
- package/server/utils/revenexxApi.ts +136 -0
- package/server/utils/schemaService.ts +25 -0
- package/server/utils/serviceMode.ts +70 -0
- package/server/utils/shippingService.ts +14 -0
- package/server/utils/shopSdk.ts +88 -0
- package/server/utils/themeService.ts +16 -0
- package/server/utils/typesense.ts +27 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { OrderList } from "../../../../app/interfaces/account/order-lists";
|
|
2
|
+
|
|
3
|
+
/** Deletes an order list (owner only). */
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const user = await getAuthService(event).me(event);
|
|
6
|
+
if (!user) {
|
|
7
|
+
throw createError({ statusCode: 401, message: "Unauthorized" });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const id = getRouterParam(event, "id") ?? "";
|
|
11
|
+
const lists = await readCoverMutableJson<OrderList[]>("account/order-lists.json");
|
|
12
|
+
const record = lists.find(list => list.id === id);
|
|
13
|
+
if (!record) {
|
|
14
|
+
throw createError({ statusCode: 404, message: "List not found" });
|
|
15
|
+
}
|
|
16
|
+
if (record.owner.id !== user.$id) {
|
|
17
|
+
throw createError({ statusCode: 403, message: "Only the owner can delete this list" });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
await writeCoverMutableJson("account/order-lists.json", lists.filter(list => list.id !== id));
|
|
21
|
+
return { ok: true };
|
|
22
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { OrderList } from "../../../../app/interfaces/account/order-lists";
|
|
2
|
+
|
|
3
|
+
/** Single order list (own or organization-public). */
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const user = await getAuthService(event).me(event);
|
|
6
|
+
if (!user) {
|
|
7
|
+
throw createError({ statusCode: 401, message: "Unauthorized" });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const id = getRouterParam(event, "id") ?? "";
|
|
11
|
+
const lists = await readCoverMutableJson<OrderList[]>("account/order-lists.json");
|
|
12
|
+
const list = lists.find(l => l.id === id && (l.owner.id === user.$id || l.public));
|
|
13
|
+
if (!list) {
|
|
14
|
+
throw createError({ statusCode: 404, message: "List not found" });
|
|
15
|
+
}
|
|
16
|
+
return list;
|
|
17
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { OrderList, OrderListPosition } from "../../../../app/interfaces/account/order-lists";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Updates an order list: rename, visibility, or the full positions array
|
|
5
|
+
* (quantity changes, removals, appends). Only the owner may modify.
|
|
6
|
+
*/
|
|
7
|
+
export default defineEventHandler(async (event) => {
|
|
8
|
+
const user = await getAuthService(event).me(event);
|
|
9
|
+
if (!user) {
|
|
10
|
+
throw createError({ statusCode: 401, message: "Unauthorized" });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const id = getRouterParam(event, "id") ?? "";
|
|
14
|
+
const body = await readBody<{
|
|
15
|
+
name?: string;
|
|
16
|
+
public?: boolean;
|
|
17
|
+
positions?: OrderListPosition[];
|
|
18
|
+
appendPositions?: OrderListPosition[];
|
|
19
|
+
}>(event);
|
|
20
|
+
|
|
21
|
+
const lists = await readCoverMutableJson<OrderList[]>("account/order-lists.json");
|
|
22
|
+
const record = lists.find(list => list.id === id);
|
|
23
|
+
if (!record) {
|
|
24
|
+
throw createError({ statusCode: 404, message: "List not found" });
|
|
25
|
+
}
|
|
26
|
+
if (record.owner.id !== user.$id) {
|
|
27
|
+
throw createError({ statusCode: 403, message: "Only the owner can modify this list" });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (typeof body?.name === "string" && body.name.trim()) {
|
|
31
|
+
record.name = body.name.trim();
|
|
32
|
+
}
|
|
33
|
+
if (typeof body?.public === "boolean") {
|
|
34
|
+
record.public = body.public;
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(body?.positions)) {
|
|
37
|
+
record.positions = body.positions;
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(body?.appendPositions)) {
|
|
40
|
+
record.positions = [...record.positions, ...body.appendPositions];
|
|
41
|
+
}
|
|
42
|
+
record.updatedAt = new Date().toISOString();
|
|
43
|
+
|
|
44
|
+
await writeCoverMutableJson("account/order-lists.json", lists);
|
|
45
|
+
return record;
|
|
46
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { OrderList } from "../../../../app/interfaces/account/order-lists";
|
|
2
|
+
|
|
3
|
+
/** Order lists visible to the user: own lists plus public organization lists. */
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const user = await getAuthService(event).me(event);
|
|
6
|
+
if (!user) {
|
|
7
|
+
throw createError({ statusCode: 401, message: "Unauthorized" });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const lists = await readCoverMutableJson<OrderList[]>("account/order-lists.json");
|
|
11
|
+
return lists
|
|
12
|
+
.filter(list => list.owner.id === user.$id || list.public)
|
|
13
|
+
.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
14
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { OrderList, OrderListPosition } from "../../../../app/interfaces/account/order-lists";
|
|
2
|
+
|
|
3
|
+
/** Creates an order list, optionally pre-filled with positions. */
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const user = await getAuthService(event).me(event);
|
|
6
|
+
if (!user) {
|
|
7
|
+
throw createError({ statusCode: 401, message: "Unauthorized" });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const body = await readBody<{
|
|
11
|
+
name?: string;
|
|
12
|
+
kind?: string;
|
|
13
|
+
public?: boolean;
|
|
14
|
+
positions?: OrderListPosition[];
|
|
15
|
+
}>(event);
|
|
16
|
+
|
|
17
|
+
const name = String(body?.name ?? "").trim();
|
|
18
|
+
const kind = body?.kind === "label" ? "label" : "shopping";
|
|
19
|
+
if (!name) {
|
|
20
|
+
throw createError({ statusCode: 400, message: "name required" });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const now = new Date().toISOString();
|
|
24
|
+
const record: OrderList = {
|
|
25
|
+
id: `ol-${Date.now().toString(36)}`,
|
|
26
|
+
name,
|
|
27
|
+
kind,
|
|
28
|
+
public: Boolean(body?.public),
|
|
29
|
+
owner: { id: user.$id, name: user.name },
|
|
30
|
+
positions: Array.isArray(body?.positions) ? body.positions : [],
|
|
31
|
+
createdAt: now,
|
|
32
|
+
updatedAt: now,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const lists = await readCoverMutableJson<OrderList[]>("account/order-lists.json");
|
|
36
|
+
await writeCoverMutableJson("account/order-lists.json", [record, ...lists]);
|
|
37
|
+
return record;
|
|
38
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AccountOrderListResponse } from "../../../../app/interfaces/account/order-list";
|
|
2
|
+
|
|
3
|
+
/** Single order from the account history (live: by display number). */
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const user = await getAuthService(event).me(event);
|
|
6
|
+
if (!user) {
|
|
7
|
+
throw createError({ statusCode: 401, message: "Unauthorized" });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const id = getRouterParam(event, "id") ?? "";
|
|
11
|
+
|
|
12
|
+
if (resolveOrderServiceKey(event) === "api") {
|
|
13
|
+
try {
|
|
14
|
+
const order = await getLiveOrderByNumber(id);
|
|
15
|
+
if (!order) {
|
|
16
|
+
throw createError({ statusCode: 404, message: "Order not found" });
|
|
17
|
+
}
|
|
18
|
+
return mapLiveOrderToAccount(order);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (isError(err)) {
|
|
22
|
+
throw err;
|
|
23
|
+
}
|
|
24
|
+
getLogService().error("Live order detail failed", apiErrorContext(err));
|
|
25
|
+
throw createError({ statusCode: 502, message: "Order service unavailable" });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const history = await readCoverMutableJson<AccountOrderListResponse>("account/order-list.json");
|
|
30
|
+
const order = history.orders.find(o => o.id === id);
|
|
31
|
+
if (!order) {
|
|
32
|
+
throw createError({ statusCode: 404, message: "Order not found" });
|
|
33
|
+
}
|
|
34
|
+
return order;
|
|
35
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AccountOrderListResponse } from "../../../app/interfaces/account/order-list";
|
|
2
|
+
import type { LiveOrder } from "../../utils/liveOrders";
|
|
3
|
+
|
|
4
|
+
const LIVE_HISTORY_LIMIT = 20;
|
|
5
|
+
|
|
6
|
+
export default defineEventHandler(async (event): Promise<AccountOrderListResponse> => {
|
|
7
|
+
if (resolveOrderServiceKey(event) === "api") {
|
|
8
|
+
const refs = sessionOrderRefs(event);
|
|
9
|
+
if (!refs.contact_id) {
|
|
10
|
+
return { orders: [] };
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const api = useRevenexxApi();
|
|
14
|
+
const { items } = await api.get<{ items: LiveOrder[] }>("/v1/orders", {
|
|
15
|
+
contact_id: refs.contact_id,
|
|
16
|
+
limit: LIVE_HISTORY_LIMIT,
|
|
17
|
+
});
|
|
18
|
+
// The list rows carry no positions — load the aggregates (the
|
|
19
|
+
// history is capped, so this stays a bounded fan-out).
|
|
20
|
+
const aggregates = await Promise.all(
|
|
21
|
+
items.map(row => api.get<LiveOrder>(`/v1/orders/${row.id}`)),
|
|
22
|
+
);
|
|
23
|
+
const orders = aggregates
|
|
24
|
+
.sort((a, b) => (b.placed_at ?? b.created_at).localeCompare(a.placed_at ?? a.created_at))
|
|
25
|
+
.map(mapLiveOrderToAccount);
|
|
26
|
+
return { orders };
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
getLogService().error("Live order history failed", apiErrorContext(err));
|
|
30
|
+
throw createError({ statusCode: 502, message: "Order service unavailable" });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return readCoverMutableJson<AccountOrderListResponse>("account/order-list.json");
|
|
35
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { StoredSession } from "../../../app/interfaces/auth";
|
|
2
|
+
|
|
3
|
+
interface AccountProfileResponse {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly email: string;
|
|
6
|
+
readonly phone: string;
|
|
7
|
+
readonly company: string;
|
|
8
|
+
readonly initials: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface AccountProfileRaw {
|
|
12
|
+
readonly userId: string;
|
|
13
|
+
readonly name?: string;
|
|
14
|
+
readonly email?: string;
|
|
15
|
+
readonly profile: {
|
|
16
|
+
readonly phone: string;
|
|
17
|
+
readonly company: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default defineEventHandler(async (event): Promise<AccountProfileResponse> => {
|
|
22
|
+
// Session guard — the profile endpoint always requires a login, regardless
|
|
23
|
+
// of which identity implementation resolves the user below.
|
|
24
|
+
const rawSession = getCookie(event, SESSION_COOKIE_NAME);
|
|
25
|
+
if (!rawSession) {
|
|
26
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
27
|
+
}
|
|
28
|
+
let session: StoredSession;
|
|
29
|
+
try {
|
|
30
|
+
session = JSON.parse(rawSession) as StoredSession;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
deleteCookie(event, SESSION_COOKIE_NAME, sessionCookieOptions());
|
|
34
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
35
|
+
}
|
|
36
|
+
if (!session.fallbackCookie && !session.personaId) {
|
|
37
|
+
deleteCookie(event, SESSION_COOKIE_NAME, sessionCookieOptions());
|
|
38
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Identity comes from the registry: "mock" serves the demo user, "sdk"
|
|
42
|
+
// resolves the real account through the platform.
|
|
43
|
+
const user = await getAccountService(event).getUser(event);
|
|
44
|
+
|
|
45
|
+
// Profile extras (phone, company) live in the mutable demo store until a
|
|
46
|
+
// platform profile capability exists.
|
|
47
|
+
const profileData = await readCoverMutableJson<AccountProfileRaw>("account/profile.json");
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
name: user.name,
|
|
51
|
+
email: user.email,
|
|
52
|
+
phone: profileData.profile.phone,
|
|
53
|
+
company: profileData.profile.company,
|
|
54
|
+
initials: user.initials,
|
|
55
|
+
};
|
|
56
|
+
});
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { StoredSession } from "../../../app/interfaces/auth";
|
|
2
|
+
interface AccountProfileResponse {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly email: string;
|
|
5
|
+
readonly phone: string;
|
|
6
|
+
readonly company: string;
|
|
7
|
+
readonly initials: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface AccountProfileRaw {
|
|
11
|
+
readonly userId: string;
|
|
12
|
+
readonly name?: string;
|
|
13
|
+
readonly email?: string;
|
|
14
|
+
readonly profile: {
|
|
15
|
+
readonly phone: string;
|
|
16
|
+
readonly company: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface AccountProfileUpdateBody {
|
|
21
|
+
readonly phone?: unknown;
|
|
22
|
+
readonly company?: unknown;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function createInitials(name: string): string {
|
|
26
|
+
const parts = name
|
|
27
|
+
.trim()
|
|
28
|
+
.split(/\s+/)
|
|
29
|
+
.filter(Boolean);
|
|
30
|
+
|
|
31
|
+
if (parts.length === 0) {
|
|
32
|
+
return "";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return parts
|
|
36
|
+
.slice(0, 2)
|
|
37
|
+
.map(part => part[0]?.toUpperCase() ?? "")
|
|
38
|
+
.join("");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function normalizeProfileValue(value: unknown): string {
|
|
42
|
+
if (typeof value !== "string") {
|
|
43
|
+
throw createError({
|
|
44
|
+
statusCode: 422,
|
|
45
|
+
statusMessage: "Invalid profile payload",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return value.trim();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function validateProfileValue(value: string, maxLength: number, field: string): void {
|
|
53
|
+
if (value.length > maxLength) {
|
|
54
|
+
throw createError({
|
|
55
|
+
statusCode: 422,
|
|
56
|
+
statusMessage: `${field} is too long`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default defineEventHandler(async (event): Promise<AccountProfileResponse> => {
|
|
62
|
+
const rawSession = getCookie(event, SESSION_COOKIE_NAME);
|
|
63
|
+
if (!rawSession) {
|
|
64
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let session: StoredSession;
|
|
68
|
+
try {
|
|
69
|
+
session = JSON.parse(rawSession) as StoredSession;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
deleteCookie(event, SESSION_COOKIE_NAME, sessionCookieOptions());
|
|
73
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!session.fallbackCookie) {
|
|
77
|
+
deleteCookie(event, SESSION_COOKIE_NAME, sessionCookieOptions());
|
|
78
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let user: { $id: string; name: string; email: string };
|
|
82
|
+
try {
|
|
83
|
+
const accountUser = await useAuthenticatedAccount(session.fallbackCookie).accountGet();
|
|
84
|
+
user = { $id: accountUser.$id, name: accountUser.name, email: accountUser.email };
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
deleteCookie(event, SESSION_COOKIE_NAME, sessionCookieOptions());
|
|
88
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const body = await readBody<AccountProfileUpdateBody>(event);
|
|
92
|
+
const phone = normalizeProfileValue(body.phone);
|
|
93
|
+
const company = normalizeProfileValue(body.company);
|
|
94
|
+
|
|
95
|
+
validateProfileValue(phone, 32, "phone");
|
|
96
|
+
validateProfileValue(company, 120, "company");
|
|
97
|
+
|
|
98
|
+
let profileData: AccountProfileRaw;
|
|
99
|
+
try {
|
|
100
|
+
profileData = await readCoverMutableJson<AccountProfileRaw>("account/profile.json");
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
throw createError({ statusCode: 500, statusMessage: "Profile store unavailable" });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const updatedProfileData: AccountProfileRaw = {
|
|
107
|
+
userId: user.$id,
|
|
108
|
+
name: user.name,
|
|
109
|
+
email: user.email,
|
|
110
|
+
profile: { phone, company },
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
if (!profileData || typeof profileData !== "object") {
|
|
114
|
+
throw createError({ statusCode: 500, statusMessage: "Profile store unavailable" });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Temporary dummy-store behavior: keep one writable profile document and
|
|
118
|
+
// rebind it to the current authenticated user until DB-backed records exist.
|
|
119
|
+
await writeCoverMutableJson("account/profile.json", updatedProfileData);
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
name: user.name,
|
|
123
|
+
email: user.email,
|
|
124
|
+
phone,
|
|
125
|
+
company,
|
|
126
|
+
initials: createInitials(user.name),
|
|
127
|
+
};
|
|
128
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Single requisition, visibility-checked via the requisition service. */
|
|
2
|
+
export default defineEventHandler(async (event) => {
|
|
3
|
+
const user = await getAuthService(event).me(event);
|
|
4
|
+
if (!user) {
|
|
5
|
+
throw createError({ statusCode: 401, message: "Unauthorized" });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const id = getRouterParam(event, "id") ?? "";
|
|
9
|
+
const visible = await getRequisitionService().list(user.$id);
|
|
10
|
+
const requisition = visible.find(r => r.id === id);
|
|
11
|
+
if (!requisition) {
|
|
12
|
+
throw createError({ statusCode: 404, message: "Requisition not found" });
|
|
13
|
+
}
|
|
14
|
+
return requisition;
|
|
15
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Requisitions visible to the current user. `?status=open` narrows to the
|
|
3
|
+
* loadable ones (cart); without it the full list incl. audit trail returns.
|
|
4
|
+
*/
|
|
5
|
+
export default defineEventHandler(async (event) => {
|
|
6
|
+
const user = await getAuthService(event).me(event);
|
|
7
|
+
if (!user) {
|
|
8
|
+
throw createError({ statusCode: 401, message: "Unauthorized" });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const { status } = getQuery(event);
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const service = getRequisitionService();
|
|
15
|
+
return status === "open"
|
|
16
|
+
? await service.listOpen(user.$id)
|
|
17
|
+
: await service.list(user.$id);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
getLogService().error("Service error: account/requisitions", toErrorContext(err));
|
|
21
|
+
throw createError({ statusCode: 500, message: "Internal server error" });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export default defineEventHandler(async (event) => {
|
|
2
|
+
const { email, password } = await readBody<{
|
|
3
|
+
email: string; password: string;
|
|
4
|
+
}>(event);
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
const result = await getAuthService(event).login(event, email, password);
|
|
8
|
+
|
|
9
|
+
// Live carts: hand the guest's session carts to the contact — merge
|
|
10
|
+
// into the customer's current cart or adopt them. Best-effort: a cart
|
|
11
|
+
// hiccup must never fail the login.
|
|
12
|
+
const manager = getCartManager(event);
|
|
13
|
+
if (manager && result.contactId) {
|
|
14
|
+
try {
|
|
15
|
+
await manager.claimSession(event, result.contactId);
|
|
16
|
+
}
|
|
17
|
+
catch (claimErr) {
|
|
18
|
+
getLogService().error("Cart claim on login failed", toErrorContext(claimErr));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
if (isSdkUserError(err)) {
|
|
26
|
+
throw createError({ statusCode: err.code, data: { type: err.type } });
|
|
27
|
+
}
|
|
28
|
+
if (isApiUserError(err)) {
|
|
29
|
+
throw createError({ statusCode: err.statusCode, data: { type: apiAuthErrorType(err) } });
|
|
30
|
+
}
|
|
31
|
+
if (isError(err)) {
|
|
32
|
+
throw err;
|
|
33
|
+
}
|
|
34
|
+
getLogService().error("Auth request failed: login", sdkErrorContext(err));
|
|
35
|
+
throw createError({ statusCode: 503, data: { type: "service_unavailable" } });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export default defineEventHandler(async (event) => {
|
|
2
|
+
const { email, url } = await readBody<{ email: string; url: string }>(event);
|
|
3
|
+
|
|
4
|
+
// Public-API mode: the customers app passes the recovery request through
|
|
5
|
+
// to platform auth — the mail carries `url?userId=…&secret=…`, exactly
|
|
6
|
+
// what the reset-password page expects.
|
|
7
|
+
if (resolveAuthServiceKey(event) === "api") {
|
|
8
|
+
try {
|
|
9
|
+
await useRevenexxApi().post("/v1/customers/auth/recovery", { email, url });
|
|
10
|
+
return { ok: true };
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
if (isApiUserError(err)) {
|
|
14
|
+
throw createError({ statusCode: err.statusCode, data: { type: apiAuthErrorType(err) } });
|
|
15
|
+
}
|
|
16
|
+
getLogService().error("API request failed: recovery", apiErrorContext(err));
|
|
17
|
+
throw createError({ statusCode: 503, data: { type: "service_unavailable" } });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
await useShopSdkAccount().accountCreateRecovery({ email, url });
|
|
23
|
+
return { ok: true };
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (isSdkUserError(err)) {
|
|
27
|
+
throw createError({ statusCode: err.code, data: { type: err.type } });
|
|
28
|
+
}
|
|
29
|
+
getLogService().error("SDK request failed: recovery", sdkErrorContext(err));
|
|
30
|
+
throw createError({ statusCode: 503, data: { type: "service_unavailable" } });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export default defineEventHandler(async (event) => {
|
|
2
|
+
const body = await readBody<{
|
|
3
|
+
userId: string; secret: string; password: string;
|
|
4
|
+
}>(event);
|
|
5
|
+
const { userId, secret, password } = body;
|
|
6
|
+
|
|
7
|
+
// Public-API mode: confirm the recovery through the customers app.
|
|
8
|
+
if (resolveAuthServiceKey(event) === "api") {
|
|
9
|
+
try {
|
|
10
|
+
await useRevenexxApi().put("/v1/customers/auth/recovery", {
|
|
11
|
+
user_id: userId,
|
|
12
|
+
secret,
|
|
13
|
+
password,
|
|
14
|
+
});
|
|
15
|
+
return { ok: true };
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
if (isApiUserError(err)) {
|
|
19
|
+
throw createError({ statusCode: err.statusCode, data: { type: apiAuthErrorType(err) } });
|
|
20
|
+
}
|
|
21
|
+
getLogService().error("API request failed: recovery-confirm", apiErrorContext(err));
|
|
22
|
+
throw createError({ statusCode: 503, data: { type: "service_unavailable" } });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
await useShopSdkAccount().accountUpdateRecovery({ userId, secret, password });
|
|
28
|
+
return { ok: true };
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
if (isSdkUserError(err)) {
|
|
32
|
+
throw createError({ statusCode: err.code, data: { type: err.type } });
|
|
33
|
+
}
|
|
34
|
+
getLogService().error("SDK request failed: recovery-confirm", sdkErrorContext(err));
|
|
35
|
+
throw createError({ statusCode: 503, data: { type: "service_unavailable" } });
|
|
36
|
+
}
|
|
37
|
+
});
|