shutro-erp 0.3.3 → 0.3.5
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/dist/account_portal/.kosh/bindings.js +1 -1
- package/dist/account_portal/.kosh/schema.d.ts +181 -3
- package/dist/account_portal/module.d.ts +359 -6
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +181 -3
- package/dist/accounting/index.js +214 -2
- package/dist/accounting/module.d.ts +217 -5
- package/dist/accounting/module.js +23 -2
- package/dist/calendar/.kosh/bindings.d.ts +22 -0
- package/dist/calendar/.kosh/bindings.js +15 -0
- package/dist/calendar/.kosh/schema.d.ts +795 -0
- package/dist/calendar/demo.d.ts +6 -0
- package/dist/calendar/demo.js +24 -0
- package/dist/calendar/index.d.ts +3 -0
- package/dist/calendar/index.js +291 -0
- package/dist/calendar/module.d.ts +1705 -0
- package/dist/calendar/module.js +180 -0
- package/dist/cli/init.js +48 -0
- package/dist/cli/templates.d.ts +1 -1
- package/dist/cli/templates.js +137 -0
- package/dist/contacts/.kosh/bindings.js +1 -1
- package/dist/contacts/.kosh/schema.d.ts +205 -3
- package/dist/contacts/demo.js +30 -1
- package/dist/contacts/index.d.ts +1 -1
- package/dist/contacts/index.js +155 -9
- package/dist/contacts/module.d.ts +338 -2
- package/dist/contacts/module.js +82 -5
- package/dist/crm/.kosh/bindings.d.ts +22 -0
- package/dist/crm/.kosh/bindings.js +15 -0
- package/dist/crm/.kosh/schema.d.ts +799 -0
- package/dist/crm/demo.d.ts +6 -0
- package/dist/crm/demo.js +45 -0
- package/dist/crm/index.d.ts +3 -0
- package/dist/crm/index.js +361 -0
- package/dist/crm/module.d.ts +1843 -0
- package/dist/crm/module.js +207 -0
- package/dist/event/.kosh/bindings.d.ts +22 -0
- package/dist/event/.kosh/bindings.js +15 -0
- package/dist/event/.kosh/schema.d.ts +843 -0
- package/dist/event/demo.d.ts +6 -0
- package/dist/event/demo.js +65 -0
- package/dist/event/index.d.ts +14 -0
- package/dist/event/index.js +333 -0
- package/dist/event/mails.d.ts +15 -0
- package/dist/event/mails.js +112 -0
- package/dist/event/module.d.ts +2800 -0
- package/dist/event/module.js +323 -0
- package/dist/event/web/CheckInBox.d.ts +9 -0
- package/dist/event/web/CheckInBox.js +87 -0
- package/dist/event/web/index.d.ts +11 -0
- package/dist/event/web/index.js +16 -0
- package/dist/event/web/messages.d.ts +2 -0
- package/dist/event/web/messages.js +23 -0
- package/dist/event_account/.kosh/bindings.d.ts +22 -0
- package/dist/event_account/.kosh/bindings.js +15 -0
- package/dist/event_account/.kosh/schema.d.ts +1639 -0
- package/dist/event_account/index.d.ts +3 -0
- package/dist/event_account/index.js +28 -0
- package/dist/event_account/module.d.ts +6968 -0
- package/dist/event_account/module.js +90 -0
- package/dist/hr/.kosh/bindings.d.ts +22 -0
- package/dist/hr/.kosh/bindings.js +15 -0
- package/dist/hr/.kosh/schema.d.ts +878 -0
- package/dist/hr/demo.d.ts +6 -0
- package/dist/hr/demo.js +60 -0
- package/dist/hr/index.d.ts +3 -0
- package/dist/hr/index.js +483 -0
- package/dist/hr/module.d.ts +2611 -0
- package/dist/hr/module.js +350 -0
- package/dist/integrations/index.js +12 -0
- package/dist/integrations/web/OAuthAppsPage.d.ts +9 -0
- package/dist/integrations/web/OAuthAppsPage.js +79 -0
- package/dist/integrations/web/index.d.ts +1 -0
- package/dist/integrations/web/index.js +3 -0
- package/dist/integrations/web/messages.js +58 -0
- package/dist/l10n_bd/.kosh/bindings.js +1 -1
- package/dist/l10n_bd/.kosh/schema.d.ts +181 -3
- package/dist/l10n_bd/module.d.ts +359 -6
- package/dist/l10n_in/.kosh/bindings.js +1 -1
- package/dist/l10n_in/.kosh/schema.d.ts +181 -3
- package/dist/l10n_in/module.d.ts +380 -7
- package/dist/maintenance/.kosh/bindings.d.ts +22 -0
- package/dist/maintenance/.kosh/bindings.js +15 -0
- package/dist/maintenance/.kosh/schema.d.ts +911 -0
- package/dist/maintenance/demo.d.ts +6 -0
- package/dist/maintenance/demo.js +60 -0
- package/dist/maintenance/index.d.ts +3 -0
- package/dist/maintenance/index.js +422 -0
- package/dist/maintenance/module.d.ts +3545 -0
- package/dist/maintenance/module.js +446 -0
- package/dist/maintenance_stock/.kosh/bindings.d.ts +22 -0
- package/dist/maintenance_stock/.kosh/bindings.js +15 -0
- package/dist/maintenance_stock/.kosh/schema.d.ts +1371 -0
- package/dist/maintenance_stock/index.d.ts +9 -0
- package/dist/maintenance_stock/index.js +52 -0
- package/dist/maintenance_stock/module.d.ts +6953 -0
- package/dist/maintenance_stock/module.js +192 -0
- package/dist/messaging/web/index.js +1 -1
- package/dist/modules-sdk/index.d.ts +1 -1
- package/dist/modules-sdk/manifest.d.ts +70 -0
- package/dist/modules-sdk/manifest.js +35 -1
- package/dist/mrp/.kosh/bindings.d.ts +22 -0
- package/dist/mrp/.kosh/bindings.js +15 -0
- package/dist/mrp/.kosh/schema.d.ts +1378 -0
- package/dist/mrp/demo.d.ts +7 -0
- package/dist/mrp/demo.js +42 -0
- package/dist/mrp/index.d.ts +3 -0
- package/dist/mrp/index.js +392 -0
- package/dist/mrp/module.d.ts +8608 -0
- package/dist/mrp/module.js +695 -0
- package/dist/mrp_account/.kosh/bindings.d.ts +22 -0
- package/dist/mrp_account/.kosh/bindings.js +15 -0
- package/dist/mrp_account/.kosh/schema.d.ts +2106 -0
- package/dist/mrp_account/index.d.ts +3 -0
- package/dist/mrp_account/index.js +22 -0
- package/dist/mrp_account/module.d.ts +20840 -0
- package/dist/mrp_account/module.js +123 -0
- package/dist/notify/web/index.js +1 -1
- package/dist/payment/.kosh/bindings.js +1 -1
- package/dist/payment/.kosh/schema.d.ts +181 -3
- package/dist/payment/module.d.ts +359 -6
- package/dist/portal/.kosh/bindings.js +1 -1
- package/dist/portal/.kosh/schema.d.ts +205 -3
- package/dist/portal/module.d.ts +166 -2
- package/dist/pos/.kosh/bindings.d.ts +22 -0
- package/dist/pos/.kosh/bindings.js +15 -0
- package/dist/pos/.kosh/schema.d.ts +1690 -0
- package/dist/pos/accounting.d.ts +10 -0
- package/dist/pos/accounting.js +149 -0
- package/dist/pos/demo.d.ts +6 -0
- package/dist/pos/demo.js +90 -0
- package/dist/pos/index.d.ts +9 -0
- package/dist/pos/index.js +349 -0
- package/dist/pos/module.d.ts +9636 -0
- package/dist/pos/module.js +423 -0
- package/dist/pos/routes.d.ts +39 -0
- package/dist/pos/routes.js +368 -0
- package/dist/pos/web/Register.d.ts +9 -0
- package/dist/pos/web/Register.js +252 -0
- package/dist/pos/web/index.d.ts +11 -0
- package/dist/pos/web/index.js +16 -0
- package/dist/pos/web/messages.d.ts +2 -0
- package/dist/pos/web/messages.js +87 -0
- package/dist/pos_stock/.kosh/bindings.d.ts +22 -0
- package/dist/pos_stock/.kosh/bindings.js +15 -0
- package/dist/pos_stock/.kosh/schema.d.ts +2015 -0
- package/dist/pos_stock/index.d.ts +9 -0
- package/dist/pos_stock/index.js +35 -0
- package/dist/pos_stock/module.d.ts +11935 -0
- package/dist/pos_stock/module.js +115 -0
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +178 -1
- package/dist/product/index.js +81 -4
- package/dist/product/module.d.ts +43 -1
- package/dist/product/module.js +9 -2
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +181 -3
- package/dist/project/index.js +147 -7
- package/dist/project/module.d.ts +210 -2
- package/dist/project/module.js +52 -5
- package/dist/project_portal/.kosh/bindings.js +1 -1
- package/dist/project_portal/.kosh/schema.d.ts +181 -3
- package/dist/project_portal/module.d.ts +353 -4
- package/dist/purchase/.kosh/bindings.js +1 -1
- package/dist/purchase/.kosh/schema.d.ts +181 -3
- package/dist/purchase/index.js +163 -3
- package/dist/purchase/module.d.ts +215 -3
- package/dist/purchase/module.js +21 -3
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +182 -3
- package/dist/purchase_account/index.js +26 -1
- package/dist/purchase_account/module.d.ts +393 -7
- package/dist/purchase_portal/.kosh/bindings.js +1 -1
- package/dist/purchase_portal/.kosh/schema.d.ts +181 -3
- package/dist/purchase_portal/module.d.ts +366 -5
- package/dist/purchase_stock/.kosh/bindings.d.ts +22 -0
- package/dist/purchase_stock/.kosh/bindings.js +15 -0
- package/dist/purchase_stock/.kosh/schema.d.ts +1310 -0
- package/dist/purchase_stock/index.d.ts +7 -0
- package/dist/purchase_stock/index.js +91 -0
- package/dist/purchase_stock/module.d.ts +6763 -0
- package/dist/purchase_stock/module.js +144 -0
- package/dist/purchase_stock_account/.kosh/bindings.d.ts +22 -0
- package/dist/purchase_stock_account/.kosh/bindings.js +15 -0
- package/dist/purchase_stock_account/.kosh/schema.d.ts +1959 -0
- package/dist/purchase_stock_account/index.d.ts +3 -0
- package/dist/purchase_stock_account/index.js +24 -0
- package/dist/purchase_stock_account/module.d.ts +35366 -0
- package/dist/purchase_stock_account/module.js +162 -0
- package/dist/recruitment/.kosh/bindings.d.ts +22 -0
- package/dist/recruitment/.kosh/bindings.js +15 -0
- package/dist/recruitment/.kosh/schema.d.ts +990 -0
- package/dist/recruitment/demo.d.ts +6 -0
- package/dist/recruitment/demo.js +45 -0
- package/dist/recruitment/index.d.ts +3 -0
- package/dist/recruitment/index.js +385 -0
- package/dist/recruitment/module.d.ts +3247 -0
- package/dist/recruitment/module.js +193 -0
- package/dist/recruitment/web/HireButton.d.ts +9 -0
- package/dist/recruitment/web/HireButton.js +32 -0
- package/dist/recruitment/web/index.d.ts +11 -0
- package/dist/recruitment/web/index.js +16 -0
- package/dist/recruitment/web/messages.d.ts +2 -0
- package/dist/recruitment/web/messages.js +19 -0
- package/dist/reporting/documents.d.ts +5 -0
- package/dist/reporting/documents.js +28 -1
- package/dist/reporting/index.d.ts +1 -1
- package/dist/reporting/index.js +4 -2
- package/dist/reporting/models.js +9 -0
- package/dist/reporting/overviews.d.ts +16 -0
- package/dist/reporting/overviews.js +56 -0
- package/dist/reporting/routes-documents.js +1 -1
- package/dist/reporting/routes.js +138 -80
- package/dist/reporting/web/DashboardView.d.ts +11 -0
- package/dist/reporting/web/DashboardView.js +2 -2
- package/dist/reporting/web/DesignerView.js +5 -0
- package/dist/reporting/web/Overview.d.ts +9 -0
- package/dist/reporting/web/Overview.js +53 -0
- package/dist/reporting/web/index.d.ts +1 -0
- package/dist/reporting/web/index.js +4 -1
- package/dist/reporting/web/messages.js +9 -0
- package/dist/sale_account/.kosh/bindings.js +1 -1
- package/dist/sale_account/.kosh/schema.d.ts +186 -3
- package/dist/sale_account/index.js +22 -1
- package/dist/sale_account/module.d.ts +461 -7
- package/dist/sale_portal/.kosh/bindings.js +1 -1
- package/dist/sale_portal/.kosh/schema.d.ts +185 -3
- package/dist/sale_portal/module.d.ts +434 -5
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +187 -3
- package/dist/sale_project/module.d.ts +476 -6
- package/dist/sale_stock/.kosh/bindings.d.ts +22 -0
- package/dist/sale_stock/.kosh/bindings.js +15 -0
- package/dist/sale_stock/.kosh/schema.d.ts +1228 -0
- package/dist/sale_stock/index.d.ts +7 -0
- package/dist/sale_stock/index.js +84 -0
- package/dist/sale_stock/module.d.ts +6791 -0
- package/dist/sale_stock/module.js +146 -0
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +185 -3
- package/dist/sales/index.js +191 -4
- package/dist/sales/module.d.ts +355 -3
- package/dist/sales/module.js +78 -3
- package/dist/server/api/metadata.d.ts +5 -0
- package/dist/server/api/metadata.js +5 -0
- package/dist/server/api/rest.js +64 -1
- package/dist/server/api/views.js +1 -0
- package/dist/server/app-settings.d.ts +7 -0
- package/dist/server/app-settings.js +10 -0
- package/dist/server/auth/base.js +85 -0
- package/dist/server/auth/oauth.d.ts +21 -0
- package/dist/server/auth/oauth.js +579 -0
- package/dist/server/auth/service.d.ts +4 -0
- package/dist/server/auth/service.js +17 -0
- package/dist/server/identity.d.ts +2 -0
- package/dist/server/images.d.ts +12 -0
- package/dist/server/images.js +139 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +2 -0
- package/dist/server/server.d.ts +4 -0
- package/dist/server/server.js +9 -1
- package/dist/settings/app-settings.d.ts +2 -0
- package/dist/settings/app-settings.js +518 -0
- package/dist/settings/company.js +3 -1
- package/dist/settings/index.d.ts +1 -0
- package/dist/settings/index.js +15 -0
- package/dist/settings/people.js +32 -6
- package/dist/settings/web/AppSettingsPage.d.ts +11 -0
- package/dist/settings/web/AppSettingsPage.js +210 -0
- package/dist/settings/web/CompaniesPage.js +2 -2
- package/dist/settings/web/CompanyPage.js +13 -2
- package/dist/settings/web/ConnectedAppsPage.d.ts +7 -0
- package/dist/settings/web/ConnectedAppsPage.js +33 -0
- package/dist/settings/web/OverviewPage.js +28 -4
- package/dist/settings/web/PeoplePage.js +23 -18
- package/dist/settings/web/ProfilePage.js +9 -7
- package/dist/settings/web/index.d.ts +2 -0
- package/dist/settings/web/index.js +8 -0
- package/dist/settings/web/messages.js +146 -2
- package/dist/stock/.kosh/bindings.d.ts +22 -0
- package/dist/stock/.kosh/bindings.js +15 -0
- package/dist/stock/.kosh/schema.d.ts +1147 -0
- package/dist/stock/demo.d.ts +7 -0
- package/dist/stock/demo.js +55 -0
- package/dist/stock/index.d.ts +3 -0
- package/dist/stock/index.js +674 -0
- package/dist/stock/module.d.ts +6330 -0
- package/dist/stock/module.js +1325 -0
- package/dist/stock/web/ScanBox.d.ts +8 -0
- package/dist/stock/web/ScanBox.js +90 -0
- package/dist/stock/web/index.d.ts +11 -0
- package/dist/stock/web/index.js +16 -0
- package/dist/stock/web/messages.d.ts +2 -0
- package/dist/stock/web/messages.js +25 -0
- package/dist/stock_account/.kosh/bindings.d.ts +22 -0
- package/dist/stock_account/.kosh/bindings.js +15 -0
- package/dist/stock_account/.kosh/schema.d.ts +1875 -0
- package/dist/stock_account/index.d.ts +3 -0
- package/dist/stock_account/index.js +130 -0
- package/dist/stock_account/module.d.ts +10655 -0
- package/dist/stock_account/module.js +339 -0
- package/dist/storage/attachments.d.ts +5 -0
- package/dist/storage/attachments.js +12 -1
- package/dist/storage/models.js +3 -0
- package/dist/storage/routes.js +13 -2
- package/dist/todo/.kosh/bindings.d.ts +22 -0
- package/dist/todo/.kosh/bindings.js +15 -0
- package/dist/todo/.kosh/schema.d.ts +732 -0
- package/dist/todo/demo.d.ts +6 -0
- package/dist/todo/demo.js +35 -0
- package/dist/todo/index.d.ts +3 -0
- package/dist/todo/index.js +187 -0
- package/dist/todo/module.d.ts +1180 -0
- package/dist/todo/module.js +130 -0
- package/dist/trade_finance/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance/.kosh/bindings.js +15 -0
- package/dist/trade_finance/.kosh/schema.d.ts +884 -0
- package/dist/trade_finance/demo.d.ts +6 -0
- package/dist/trade_finance/demo.js +63 -0
- package/dist/trade_finance/index.d.ts +3 -0
- package/dist/trade_finance/index.js +413 -0
- package/dist/trade_finance/module.d.ts +3779 -0
- package/dist/trade_finance/module.js +505 -0
- package/dist/trade_finance_account/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance_account/.kosh/bindings.js +15 -0
- package/dist/trade_finance_account/.kosh/schema.d.ts +1711 -0
- package/dist/trade_finance_account/index.d.ts +3 -0
- package/dist/trade_finance_account/index.js +92 -0
- package/dist/trade_finance_account/module.d.ts +7928 -0
- package/dist/trade_finance_account/module.js +244 -0
- package/dist/trade_finance_purchase/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance_purchase/.kosh/bindings.js +15 -0
- package/dist/trade_finance_purchase/.kosh/schema.d.ts +1153 -0
- package/dist/trade_finance_purchase/index.d.ts +8 -0
- package/dist/trade_finance_purchase/index.js +50 -0
- package/dist/trade_finance_purchase/module.d.ts +4252 -0
- package/dist/trade_finance_purchase/module.js +44 -0
- package/dist/trade_finance_sale/.kosh/bindings.d.ts +22 -0
- package/dist/trade_finance_sale/.kosh/bindings.js +15 -0
- package/dist/trade_finance_sale/.kosh/schema.d.ts +1071 -0
- package/dist/trade_finance_sale/index.d.ts +8 -0
- package/dist/trade_finance_sale/index.js +50 -0
- package/dist/trade_finance_sale/module.d.ts +4280 -0
- package/dist/trade_finance_sale/module.js +44 -0
- package/dist/ui/api.d.ts +6 -1
- package/dist/ui/api.js +2 -1
- package/dist/ui/app.js +51 -17
- package/dist/ui/components/AppIcon.js +33 -1
- package/dist/ui/components/Avatar.d.ts +21 -0
- package/dist/ui/components/Avatar.js +71 -0
- package/dist/ui/components/primitives.d.ts +2 -0
- package/dist/ui/components/primitives.js +7 -1
- package/dist/ui/i18n/messages.d.ts +53 -0
- package/dist/ui/i18n/messages.js +98 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +2 -0
- package/dist/ui/offline/queue.d.ts +5 -1
- package/dist/ui/offline/queue.js +2 -0
- package/dist/ui/registry.d.ts +12 -1
- package/dist/ui/registry.js +10 -1
- package/dist/ui/search/ViewTabs.d.ts +14 -0
- package/dist/ui/search/ViewTabs.js +42 -0
- package/dist/ui/shell/Consent.d.ts +5 -0
- package/dist/ui/shell/Consent.js +35 -0
- package/dist/ui/shell/Home.js +136 -16
- package/dist/ui/shell/Sidebar.js +15 -22
- package/dist/ui/views/FormView.js +98 -17
- package/dist/ui/views/KanbanView.d.ts +2 -0
- package/dist/ui/views/KanbanView.js +32 -3
- package/dist/ui/views/ListView.js +155 -31
- package/dist/ui/views/StatsRow.d.ts +14 -0
- package/dist/ui/views/StatsRow.js +88 -0
- package/dist/ui/views/widgets.d.ts +2 -1
- package/dist/ui/views/widgets.js +194 -1
- package/dist/views/builders.d.ts +19 -2
- package/dist/views/builders.js +21 -1
- package/dist/views/condition.d.ts +6 -0
- package/dist/views/condition.js +20 -0
- package/dist/views/documents.d.ts +8 -0
- package/dist/views/extend.d.ts +2 -2
- package/dist/views/extend.js +11 -1
- package/dist/views/index.d.ts +2 -2
- package/dist/views/index.js +2 -2
- package/dist/views/types.d.ts +52 -5
- package/dist/views/validate.js +39 -1
- package/dist/website/.kosh/bindings.d.ts +22 -0
- package/dist/website/.kosh/bindings.js +15 -0
- package/dist/website/.kosh/schema.d.ts +881 -0
- package/dist/website/demo.d.ts +6 -0
- package/dist/website/demo.js +115 -0
- package/dist/website/index.d.ts +9 -0
- package/dist/website/index.js +250 -0
- package/dist/website/module.d.ts +2987 -0
- package/dist/website/module.js +281 -0
- package/dist/website/render.d.ts +45 -0
- package/dist/website/render.js +102 -0
- package/dist/website/routes.d.ts +12 -0
- package/dist/website/routes.js +246 -0
- package/dist/website/web/PagePreview.d.ts +7 -0
- package/dist/website/web/PagePreview.js +33 -0
- package/dist/website/web/index.d.ts +11 -0
- package/dist/website/web/index.js +16 -0
- package/dist/website/web/messages.d.ts +2 -0
- package/dist/website/web/messages.js +15 -0
- package/dist/website_crm/.kosh/bindings.d.ts +22 -0
- package/dist/website_crm/.kosh/bindings.js +15 -0
- package/dist/website_crm/.kosh/schema.d.ts +966 -0
- package/dist/website_crm/index.d.ts +3 -0
- package/dist/website_crm/index.js +39 -0
- package/dist/website_crm/module.d.ts +2955 -0
- package/dist/website_crm/module.js +44 -0
- package/package.json +118 -1
package/dist/server/api/rest.js
CHANGED
|
@@ -266,7 +266,45 @@ export function registerRestApi(app, options) {
|
|
|
266
266
|
!Array.isArray(changed) ||
|
|
267
267
|
changed.some((c) => typeof c !== 'string'))
|
|
268
268
|
throw problem(400, 'invalid-body', 'Invalid onchange request', 'The body is { values: { ...the record }, changed: ["field", ...] }.');
|
|
269
|
-
|
|
269
|
+
// Datetimes arrive as ISO strings, as for create and update.
|
|
270
|
+
const values = coerceValues(model, input.values);
|
|
271
|
+
return request.env((env) => ref(env, model.name).onchange({ ...input, values }));
|
|
272
|
+
});
|
|
273
|
+
// RFC 0022 §3.4: what comes next for a record — the transitions from its state the user may run, and for
|
|
274
|
+
// each whether its guard lets this record go, with the guard's message when not (nothing is changed).
|
|
275
|
+
app.get('/api/v1/models/:model/:id/next', async (request) => {
|
|
276
|
+
const model = modelOf(request.params);
|
|
277
|
+
const id = idOf(request.params);
|
|
278
|
+
return request.env(async (env) => {
|
|
279
|
+
const stateFields = [...new Set(model.transitionSpecs.map((t) => t.field))];
|
|
280
|
+
const set = await ref(env, model.name)
|
|
281
|
+
.browse([id])
|
|
282
|
+
.load(['id', ...stateFields]);
|
|
283
|
+
const [current] = set.read(['id', ...stateFields]);
|
|
284
|
+
if (current === undefined)
|
|
285
|
+
throw new HttpProblem(404, 'missing-record', 'Not found', `No ${model.name} has the id ${id}.`);
|
|
286
|
+
const canWrite = env.access.can(model.name, 'write');
|
|
287
|
+
const transitions = [];
|
|
288
|
+
for (const t of model.transitionSpecs) {
|
|
289
|
+
if (!canWrite || (t.requires !== null && !permitted(env, t.requires)))
|
|
290
|
+
continue;
|
|
291
|
+
if (!t.from.includes(String(current[t.field] ?? '')))
|
|
292
|
+
continue;
|
|
293
|
+
let allowed = true;
|
|
294
|
+
if (t.guard !== null) {
|
|
295
|
+
const refused = idsIn(await t.guard(set));
|
|
296
|
+
allowed = !refused.includes(id);
|
|
297
|
+
}
|
|
298
|
+
transitions.push({
|
|
299
|
+
name: t.name,
|
|
300
|
+
field: t.field,
|
|
301
|
+
to: t.to,
|
|
302
|
+
allowed,
|
|
303
|
+
message: allowed ? null : t.message,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return { transitions };
|
|
307
|
+
}, { write: true }); // guards that read through asSuperuser audit the scope
|
|
270
308
|
});
|
|
271
309
|
app.post('/api/v1/models/:model/:id/transitions/:name', async (request, reply) => {
|
|
272
310
|
const model = modelOf(request.params);
|
|
@@ -458,3 +496,28 @@ export function registerRestApi(app, options) {
|
|
|
458
496
|
return options.openapi();
|
|
459
497
|
});
|
|
460
498
|
}
|
|
499
|
+
/** Whether `env` holds the feature permission `code` (an unknown code: no). */
|
|
500
|
+
function permitted(env, code) {
|
|
501
|
+
try {
|
|
502
|
+
return env.access.has(code);
|
|
503
|
+
}
|
|
504
|
+
catch {
|
|
505
|
+
return false;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
/** The ids a guard returned: a recordset (`ids`), records (`id`), ids, or lists of those; anything else, none. */
|
|
509
|
+
function idsIn(value) {
|
|
510
|
+
if (Array.isArray(value))
|
|
511
|
+
return value.flatMap(idsIn);
|
|
512
|
+
if (typeof value === 'number')
|
|
513
|
+
return [value];
|
|
514
|
+
if (typeof value !== 'object' || value === null)
|
|
515
|
+
return [];
|
|
516
|
+
if ('ids' in value && Array.isArray(value.ids))
|
|
517
|
+
return value.ids.flatMap(idsIn);
|
|
518
|
+
if ('id' in value)
|
|
519
|
+
return idsIn(value.id);
|
|
520
|
+
if (Symbol.iterator in value)
|
|
521
|
+
return [...value].flatMap(idsIn);
|
|
522
|
+
return [];
|
|
523
|
+
}
|
package/dist/server/api/views.js
CHANGED
|
@@ -296,6 +296,7 @@ function describe(env, model, field) {
|
|
|
296
296
|
kind: field.kind,
|
|
297
297
|
label: field.label,
|
|
298
298
|
required: field.required,
|
|
299
|
+
...(field.help === null ? {} : { help: field.help }),
|
|
299
300
|
// Field-level only: the UI combines it with `operations` (create for new records, write for existing ones).
|
|
300
301
|
readonly: field.readonly || !env.access.canField(model.name, field.key, 'write'),
|
|
301
302
|
...(field.target === null ? {} : { target: field.target }),
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installation-wide app settings (RFC 0020 §3.1): read in code by key, the declared default when unset. Company
|
|
3
|
+
* settings are `res.company` fields, read as the company's fields.
|
|
4
|
+
*/
|
|
5
|
+
import type { Env } from './orm.js';
|
|
6
|
+
/** The value of the installation setting `key` (`app.setting`), or `fallback` when it was never set. */
|
|
7
|
+
export declare function installationSetting<T>(env: Env, key: string, fallback: T): Promise<T>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The value of the installation setting `key` (`app.setting`), or `fallback` when it was never set. */
|
|
2
|
+
export async function installationSetting(env, key, fallback) {
|
|
3
|
+
return env.asSuperuser({ reason: `setting ${key}` }, async (su) => {
|
|
4
|
+
const found = await su.model('kosh.setting').search({ where: { key }, limit: 1 });
|
|
5
|
+
if (found.length === 0)
|
|
6
|
+
return fallback;
|
|
7
|
+
const [row] = (await found.load(['value'])).read(['value']);
|
|
8
|
+
return (row?.['value'] ?? fallback);
|
|
9
|
+
});
|
|
10
|
+
}
|
package/dist/server/auth/base.js
CHANGED
|
@@ -147,6 +147,79 @@ const AuthPolicy = defineModel('auth.policy', {
|
|
|
147
147
|
sessionDays: f.integer({ label: 'Session lifetime (days)' }),
|
|
148
148
|
},
|
|
149
149
|
});
|
|
150
|
+
/**
|
|
151
|
+
* OAuth 2.0 apps (RFC 0017 §5.2): third-party applications that act for a user who consented, within scopes. The
|
|
152
|
+
* client secret (confidential apps) is stored as a digest; public apps rely on PKCE. Private: managed by the
|
|
153
|
+
* Integrations routes and the OAuth flow.
|
|
154
|
+
*/
|
|
155
|
+
const OAuthApp = defineModel('oauth.app', {
|
|
156
|
+
fields: {
|
|
157
|
+
name: f.char({ required: true }),
|
|
158
|
+
clientId: f.char({ required: true, index: 'unique' }),
|
|
159
|
+
secretHash: f.char(),
|
|
160
|
+
confidential: f.boolean({ default: true }),
|
|
161
|
+
/** One per line; the redirect must match one exactly. */
|
|
162
|
+
redirectUris: f.text({ required: true }),
|
|
163
|
+
/** The scopes it may ask for, space separated (`*`, `read:<app>`, `write:<app>`). */
|
|
164
|
+
scopes: f.char({ required: true }),
|
|
165
|
+
homepage: f.char(),
|
|
166
|
+
active: f.boolean({ default: true }),
|
|
167
|
+
owner: f.many2one('res.users', { ondelete: 'set null' }),
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
/** A user's consent to an app, with the scopes granted; revoking it ends every token of it. */
|
|
171
|
+
const OAuthGrant = defineModel('oauth.grant', {
|
|
172
|
+
fields: {
|
|
173
|
+
user: f.many2one('res.users', { required: true, ondelete: 'cascade' }),
|
|
174
|
+
app: f.many2one('oauth.app', { required: true, ondelete: 'cascade' }),
|
|
175
|
+
scopes: f.char({ required: true }),
|
|
176
|
+
revoked: f.boolean({ default: false }),
|
|
177
|
+
lastUsedAt: f.datetime(),
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
/** An authorization code: once, for 10 minutes, bound to its redirect and its PKCE challenge. */
|
|
181
|
+
const OAuthCode = defineModel('oauth.code', {
|
|
182
|
+
fields: {
|
|
183
|
+
codeHash: f.char({ required: true, index: 'unique' }),
|
|
184
|
+
grant: f.many2one('oauth.grant', { required: true, ondelete: 'cascade' }),
|
|
185
|
+
redirectUri: f.char({ required: true }),
|
|
186
|
+
challenge: f.char(),
|
|
187
|
+
expiresAt: f.datetime({ required: true }),
|
|
188
|
+
used: f.boolean({ default: false }),
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
/** An access token (1 hour) and its refresh token (rotated at each use), both stored as digests. */
|
|
192
|
+
const OAuthToken = defineModel('oauth.token', {
|
|
193
|
+
fields: {
|
|
194
|
+
grant: f.many2one('oauth.grant', { required: true, ondelete: 'cascade' }),
|
|
195
|
+
accessHash: f.char({ required: true, index: 'unique' }),
|
|
196
|
+
refreshHash: f.char({ required: true, index: 'unique' }),
|
|
197
|
+
accessExpiresAt: f.datetime({ required: true }),
|
|
198
|
+
refreshExpiresAt: f.datetime({ required: true }),
|
|
199
|
+
/** No longer valid: replaced by a newer pair, or revoked. */
|
|
200
|
+
revoked: f.boolean({ default: false }),
|
|
201
|
+
/** Replaced by a newer pair: its refresh token coming back means someone else holds it. */
|
|
202
|
+
rotated: f.boolean({ default: false }),
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
/** Installation-wide app settings (RFC 0020): one value per key (`sales.something`), JSON. Private: Settings edits it. */
|
|
206
|
+
const KoshSetting = defineModel('kosh.setting', {
|
|
207
|
+
fields: {
|
|
208
|
+
key: f.char({ required: true, index: 'unique' }),
|
|
209
|
+
value: f.json(),
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
/** Profile photos and company logos (`images.ts`): small images, their bytes in base64. Private: served by routes. */
|
|
213
|
+
const KoshImage = defineModel('kosh.image', {
|
|
214
|
+
fields: {
|
|
215
|
+
ownerModel: f.char({ required: true, index: true }),
|
|
216
|
+
ownerId: f.integer({ required: true, index: true }),
|
|
217
|
+
mime: f.char({ required: true }),
|
|
218
|
+
data: f.text({ required: true }),
|
|
219
|
+
/** The bytes' digest (16 hex): the version in the image's URL. */
|
|
220
|
+
hash: f.char({ required: true }),
|
|
221
|
+
},
|
|
222
|
+
});
|
|
150
223
|
/**
|
|
151
224
|
* The security audit log (CLAUDE.md: logins, permission changes, exports, sensitive actions). Append-only: no one
|
|
152
225
|
* may change or delete events (administrators included: the REST API never serves it, and the admin API only reads).
|
|
@@ -217,6 +290,12 @@ export const baseShutro = defineModule({
|
|
|
217
290
|
AuthUserGroup,
|
|
218
291
|
AuthUserGrant,
|
|
219
292
|
AuthPolicy,
|
|
293
|
+
OAuthApp,
|
|
294
|
+
OAuthGrant,
|
|
295
|
+
OAuthCode,
|
|
296
|
+
OAuthToken,
|
|
297
|
+
KoshImage,
|
|
298
|
+
KoshSetting,
|
|
220
299
|
AuditEvent,
|
|
221
300
|
SavedView,
|
|
222
301
|
],
|
|
@@ -236,6 +315,12 @@ export const base = defineKoshModule({
|
|
|
236
315
|
'auth.user_group',
|
|
237
316
|
'auth.user_grant',
|
|
238
317
|
'auth.policy',
|
|
318
|
+
'oauth.app',
|
|
319
|
+
'oauth.grant',
|
|
320
|
+
'oauth.code',
|
|
321
|
+
'oauth.token',
|
|
322
|
+
'kosh.image',
|
|
323
|
+
'kosh.setting',
|
|
239
324
|
'audit.event',
|
|
240
325
|
],
|
|
241
326
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import type { Env, Shutro } from '../orm.js';
|
|
3
|
+
import type { KoshRegistry } from '../registry.js';
|
|
4
|
+
import type { AuthService } from './service.js';
|
|
5
|
+
export declare const ACCESS_SECONDS = 3600;
|
|
6
|
+
/** Access tokens start with it: the server tells them from sessions and API keys at a glance. */
|
|
7
|
+
export declare const ACCESS_PREFIX = "oat_";
|
|
8
|
+
export interface OAuthOptions {
|
|
9
|
+
/** The back-office's address: the consent page is `<baseUrl>/oauth/authorize`. */
|
|
10
|
+
readonly baseUrl: string;
|
|
11
|
+
}
|
|
12
|
+
/** A resolved access token: who it acts as, within which scopes. */
|
|
13
|
+
export interface OAuthAccess {
|
|
14
|
+
readonly token: number;
|
|
15
|
+
readonly user: number;
|
|
16
|
+
readonly app: number;
|
|
17
|
+
readonly scopes: string[];
|
|
18
|
+
}
|
|
19
|
+
/** Finds the access token `token` (`oat_…`), live, of an active app and a grant not revoked. */
|
|
20
|
+
export declare function resolveAccessToken(env: Env, token: string): Promise<OAuthAccess | null>;
|
|
21
|
+
export declare function registerOAuthRoutes(app: FastifyInstance, auth: AuthService, shutro: () => Shutro, registry: KoshRegistry, options: OAuthOptions): void;
|