@saltcorn/server 1.6.0-beta.1 → 1.6.0-beta.10

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.
Files changed (789) hide show
  1. package/CHANGELOG.md +72 -3
  2. package/app.js +32 -12
  3. package/auth/admin.js +109 -22
  4. package/auth/routes.js +178 -61
  5. package/auth/testhelp.js +9 -19
  6. package/docs/assets/hierarchy.js +1 -1
  7. package/docs/assets/navigation.js +1 -1
  8. package/docs/assets/search.js +1 -1
  9. package/docs/classes/_saltcorn_admin-models.models_snapshot.Snapshot.html +2 -2
  10. package/docs/classes/_saltcorn_common-code.relations_relation.Relation.html +3 -3
  11. package/docs/classes/_saltcorn_common-code.relations_relations_finder.RelationsFinder.html +5 -5
  12. package/docs/classes/_saltcorn_data.diagram_cy_raster.CytoscapeRaster.html +4 -4
  13. package/docs/classes/_saltcorn_data.diagram_nodes_dummy_node.DummyNode.html +4 -4
  14. package/docs/classes/_saltcorn_data.diagram_nodes_node.Node.html +4 -4
  15. package/docs/classes/_saltcorn_data.diagram_nodes_page_node.PageNode.html +4 -4
  16. package/docs/classes/_saltcorn_data.diagram_nodes_table_node.TableNode.html +4 -4
  17. package/docs/classes/_saltcorn_data.diagram_nodes_trigger_node.TriggerNode.html +4 -4
  18. package/docs/classes/_saltcorn_data.diagram_nodes_view_node.ViewNode.html +4 -4
  19. package/docs/classes/_saltcorn_data.mobile-mocks_node_async_hooks.AsyncLocalStorage.html +2 -2
  20. package/docs/classes/_saltcorn_data.models_crash.Crash.html +2 -2
  21. package/docs/classes/_saltcorn_data.models_eventlog.EventLog.html +2 -2
  22. package/docs/classes/_saltcorn_data.models_field.Field.html +9 -9
  23. package/docs/classes/_saltcorn_data.models_fieldrepeat.FieldRepeat.html +2 -2
  24. package/docs/classes/_saltcorn_data.models_file.File.html +21 -21
  25. package/docs/classes/_saltcorn_data.models_form.Form.html +2 -2
  26. package/docs/classes/_saltcorn_data.models_internal_mail_queue.MailQueue.html +4 -4
  27. package/docs/classes/_saltcorn_data.models_internal_push_message_helper.PushMessageHelper.html +7 -7
  28. package/docs/classes/_saltcorn_data.models_library.Library.html +2 -2
  29. package/docs/classes/_saltcorn_data.models_model.Model.html +2 -2
  30. package/docs/classes/_saltcorn_data.models_model_instance.ModelInstance.html +2 -2
  31. package/docs/classes/_saltcorn_data.models_notification.Notification.html +2 -2
  32. package/docs/classes/_saltcorn_data.models_page.Page.html +12 -11
  33. package/docs/classes/_saltcorn_data.models_page_group.PageGroup.html +16 -16
  34. package/docs/classes/_saltcorn_data.models_page_group_member.PageGroupMember.html +8 -8
  35. package/docs/classes/_saltcorn_data.models_plugin.Plugin.html +45 -10
  36. package/docs/classes/_saltcorn_data.models_role.Role.html +2 -2
  37. package/docs/classes/_saltcorn_data.models_table.Table.html +67 -65
  38. package/docs/classes/_saltcorn_data.models_table_constraints.TableConstraint.html +2 -2
  39. package/docs/classes/_saltcorn_data.models_tag.Tag.html +2 -2
  40. package/docs/classes/_saltcorn_data.models_tag_entry.TagEntry.html +2 -2
  41. package/docs/classes/_saltcorn_data.models_trigger.Trigger.html +22 -20
  42. package/docs/classes/_saltcorn_data.models_user.User.html +32 -32
  43. package/docs/classes/_saltcorn_data.models_view.View.html +16 -15
  44. package/docs/classes/_saltcorn_data.models_workflow.Workflow.html +2 -2
  45. package/docs/classes/_saltcorn_data.models_workflow_run.WorkflowRun.html +2 -2
  46. package/docs/classes/_saltcorn_data.models_workflow_step.WorkflowStep.html +2 -2
  47. package/docs/classes/_saltcorn_data.models_workflow_trace.MetaData.html +2 -2
  48. package/docs/classes/_saltcorn_data.models_workflow_trace.WorkflowTrace.html +2 -2
  49. package/docs/classes/_saltcorn_mobile-builder.mobile-builder.MobileBuilder.html +2 -3
  50. package/docs/classes/_saltcorn_mobile-builder.utils_capacitor-helper.CapacitorHelper.html +2 -2
  51. package/docs/enums/_saltcorn_common-code.relations_relation_types.RelationType.html +2 -2
  52. package/docs/enums/_saltcorn_common-code.relations_relation_types.ViewDisplayType.html +2 -2
  53. package/docs/functions/_saltcorn_admin-models.models_config-check.runConfigurationCheck.html +1 -1
  54. package/docs/functions/_saltcorn_common-code.relations_relation_helpers.buildRelationPath.html +1 -1
  55. package/docs/functions/_saltcorn_common-code.relations_relation_helpers.buildTableCaches.html +1 -1
  56. package/docs/functions/_saltcorn_common-code.relations_relation_helpers.parseLegacyRelation.html +1 -1
  57. package/docs/functions/_saltcorn_common-code.relations_relation_helpers.parseRelationPath.html +1 -1
  58. package/docs/functions/_saltcorn_common-code.tests_test_data.fixturesData.html +1 -1
  59. package/docs/functions/_saltcorn_common-code.tests_test_data.withAnotherUserField.html +1 -1
  60. package/docs/functions/_saltcorn_common-code.tests_test_data.withKeyFromLayerThree.html +1 -1
  61. package/docs/functions/_saltcorn_common-code.tests_test_data.withKeyFromLayerTwo.html +1 -1
  62. package/docs/functions/_saltcorn_common-code.tests_test_data.withMultipleInbounds.html +1 -1
  63. package/docs/functions/_saltcorn_common-code.tests_test_data.withSecondTopicField.html +1 -1
  64. package/docs/functions/_saltcorn_common-code.tests_test_data.withSimplePostTopicrelation.html +1 -1
  65. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.action_link.html +1 -1
  66. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.action_url.html +1 -1
  67. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.fill_presets.html +1 -1
  68. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.getForm.html +1 -1
  69. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.get_view_link_query.html +1 -1
  70. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.get_viewable_fields.html +1 -1
  71. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.get_viewable_fields_from_layout.html +1 -1
  72. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.make_link.html +1 -1
  73. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.objToQueryString.html +1 -1
  74. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.parse_view_select.html +1 -1
  75. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.setDateLocales.html +1 -1
  76. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.splitUniques.html +1 -1
  77. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.standardBlockDispatch.html +1 -1
  78. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.standardLayoutRowVisitor.html +1 -1
  79. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.transformForm.html +1 -1
  80. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.updateViewSelect.html +1 -1
  81. package/docs/functions/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.view_linker.html +1 -1
  82. package/docs/functions/_saltcorn_data.db_connect_mobile.getConnectObject.html +1 -1
  83. package/docs/functions/_saltcorn_data.db_reset_schema.reset.html +1 -1
  84. package/docs/functions/_saltcorn_data.diagram_cy_generate_utils.generateCyCode.html +1 -1
  85. package/docs/functions/_saltcorn_data.diagram_cy_generate_utils.genereateCyCfg.html +1 -1
  86. package/docs/functions/_saltcorn_data.diagram_node_extract_utils.buildObjectTrees.html +1 -1
  87. package/docs/functions/_saltcorn_data.diagram_node_extract_utils.extractFromColumns.html +1 -1
  88. package/docs/functions/_saltcorn_data.diagram_node_extract_utils.extractFromLayout.html +1 -1
  89. package/docs/functions/_saltcorn_data.diagram_node_extract_utils.extractViewToCreate.html +1 -1
  90. package/docs/functions/_saltcorn_data.migrate.create_blank_migration.html +1 -1
  91. package/docs/functions/_saltcorn_data.migrate.getMigrationsInDB.html +1 -1
  92. package/docs/functions/_saltcorn_data.migrate.migrate.html +1 -1
  93. package/docs/functions/_saltcorn_data.migrations_202102091312.js.html +1 -1
  94. package/docs/functions/_saltcorn_data.migrations_202210051058.js.html +1 -1
  95. package/docs/functions/_saltcorn_data.migrations_202210101540.js.html +1 -1
  96. package/docs/functions/_saltcorn_data.migrations_202304281224.js.html +1 -1
  97. package/docs/functions/_saltcorn_data.migrations_202307211459.js.html +1 -1
  98. package/docs/functions/_saltcorn_data.migrations_202502131103.js.html +1 -1
  99. package/docs/functions/_saltcorn_data.migrations_202508011455.js.html +1 -1
  100. package/docs/functions/_saltcorn_data.migrations_202510152058.js.html +1 -1
  101. package/docs/functions/_saltcorn_data.migrations_202603101553.sql_pg.html +1 -1
  102. package/docs/functions/_saltcorn_data.migrations_202604111200.js.html +1 -0
  103. package/docs/functions/_saltcorn_data.migrations_202604141200.js.html +1 -0
  104. package/docs/functions/_saltcorn_data.mobile-mocks_node_child_process.execSync.html +1 -1
  105. package/docs/functions/_saltcorn_data.mobile-mocks_node_fs.createReadStream.html +1 -1
  106. package/docs/functions/_saltcorn_data.mobile-mocks_node_fs.readdirSync.html +1 -1
  107. package/docs/functions/_saltcorn_data.mobile-mocks_node_fs.writeFileSync.html +1 -1
  108. package/docs/functions/_saltcorn_data.mobile-mocks_node_fs_promises.mkdir.html +1 -1
  109. package/docs/functions/_saltcorn_data.mobile-mocks_node_fs_promises.readFile.html +1 -1
  110. package/docs/functions/_saltcorn_data.mobile-mocks_node_fs_promises.readdir.html +1 -0
  111. package/docs/functions/_saltcorn_data.mobile-mocks_node_fs_promises.stat.html +1 -1
  112. package/docs/functions/_saltcorn_data.mobile-mocks_node_fs_promises.unlink.html +1 -1
  113. package/docs/functions/_saltcorn_data.mobile-mocks_node_fs_promises.writeFile.html +1 -1
  114. package/docs/functions/_saltcorn_data.mobile-mocks_node_latest-version.latestVersion.html +1 -1
  115. package/docs/functions/_saltcorn_data.mobile-mocks_node_v8.deserialize.html +1 -1
  116. package/docs/functions/_saltcorn_data.mobile-mocks_node_v8.serialize.html +1 -1
  117. package/docs/functions/_saltcorn_data.mobile-mocks_npm_env-paths.envPaths.html +1 -1
  118. package/docs/functions/_saltcorn_data.model-helper.get_predictor.html +1 -1
  119. package/docs/functions/_saltcorn_data.model-helper.run_jupyter_model.html +1 -1
  120. package/docs/functions/_saltcorn_data.model-helper.shorten_trackback.html +1 -1
  121. package/docs/functions/_saltcorn_data.model-helper.write_csv.html +1 -1
  122. package/docs/functions/_saltcorn_data.models_internal_async_json_stream.async_json_stream.html +1 -1
  123. package/docs/functions/_saltcorn_data.models_internal_query.aggregation_query_fields.html +1 -1
  124. package/docs/functions/_saltcorn_data.models_internal_query.getAggAndField.html +1 -1
  125. package/docs/functions/_saltcorn_data.models_internal_query.joinfield_renamer.html +1 -1
  126. package/docs/functions/_saltcorn_data.models_internal_query.process_aggregations.html +1 -1
  127. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.buildKeyFromRelative.html +1 -1
  128. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.copyObject.html +1 -1
  129. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.deleteObject.html +1 -1
  130. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.downloadBuffer.html +1 -1
  131. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.getPublicFileUrl.html +1 -1
  132. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.getResolvedBucket.html +1 -1
  133. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.getS3Client.html +1 -1
  134. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.getServeUrl.html +1 -1
  135. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.getSignedFileUrl.html +1 -1
  136. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.headObject.html +1 -1
  137. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.isS3Enabled.html +1 -1
  138. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.listS3Folder.html +1 -1
  139. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.publicUrlToRelativePath.html +1 -1
  140. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.relativeKeyToPath.html +1 -1
  141. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.setObjectMetadata.html +1 -1
  142. package/docs/functions/_saltcorn_data.models_internal_s3_helpers.uploadBuffer.html +1 -1
  143. package/docs/functions/_saltcorn_data.models_internal_table_helper.boolExamples.html +1 -1
  144. package/docs/functions/_saltcorn_data.models_internal_table_helper.colorExamples.html +1 -1
  145. package/docs/functions/_saltcorn_data.models_internal_table_helper.floatExamples.html +1 -1
  146. package/docs/functions/_saltcorn_data.models_internal_table_helper.get_formula_examples.html +1 -1
  147. package/docs/functions/_saltcorn_data.models_internal_table_helper.intExamples.html +1 -1
  148. package/docs/functions/_saltcorn_data.models_internal_table_helper.stringExamples.html +1 -1
  149. package/docs/functions/_saltcorn_data.plugin-helper.build_schema_data.html +1 -1
  150. package/docs/functions/_saltcorn_data.plugin-helper.calcfldViewConfig.html +1 -1
  151. package/docs/functions/_saltcorn_data.plugin-helper.calcfldViewOptions.html +1 -1
  152. package/docs/functions/_saltcorn_data.plugin-helper.calcrelViewOptions.html +1 -1
  153. package/docs/functions/_saltcorn_data.plugin-helper.displayType.html +1 -1
  154. package/docs/functions/_saltcorn_data.plugin-helper.field_picker_fields.html +1 -1
  155. package/docs/functions/_saltcorn_data.plugin-helper.generate_joined_query.html +1 -1
  156. package/docs/functions/_saltcorn_data.plugin-helper.getActionConfigFields.html +1 -1
  157. package/docs/functions/_saltcorn_data.plugin-helper.get_child_views.html +1 -1
  158. package/docs/functions/_saltcorn_data.plugin-helper.get_inbound_relation_opts.html +1 -1
  159. package/docs/functions/_saltcorn_data.plugin-helper.get_inbound_self_relation_opts.html +1 -1
  160. package/docs/functions/_saltcorn_data.plugin-helper.get_link_view_opts.html +1 -1
  161. package/docs/functions/_saltcorn_data.plugin-helper.get_many_to_many_relation_opts.html +1 -1
  162. package/docs/functions/_saltcorn_data.plugin-helper.get_parent_views.html +1 -1
  163. package/docs/functions/_saltcorn_data.plugin-helper.initial_config_all_fields.html +1 -1
  164. package/docs/functions/_saltcorn_data.plugin-helper.json_list_to_external_table.html +1 -1
  165. package/docs/functions/_saltcorn_data.plugin-helper.link_view.html +1 -1
  166. package/docs/functions/_saltcorn_data.plugin-helper.pathToState.html +1 -1
  167. package/docs/functions/_saltcorn_data.plugin-helper.picked_fields_to_query.html +1 -1
  168. package/docs/functions/_saltcorn_data.plugin-helper.readState.html +1 -1
  169. package/docs/functions/_saltcorn_data.plugin-helper.readStateStrict.html +1 -1
  170. package/docs/functions/_saltcorn_data.plugin-helper.runCollabEvents.html +1 -1
  171. package/docs/functions/_saltcorn_data.plugin-helper.run_action_column.html +1 -1
  172. package/docs/functions/_saltcorn_data.plugin-helper.stateFieldsToQuery.html +1 -1
  173. package/docs/functions/_saltcorn_data.plugin-helper.stateFieldsToWhere.html +1 -1
  174. package/docs/functions/_saltcorn_data.plugin-helper.stateToQueryString.html +1 -1
  175. package/docs/functions/_saltcorn_data.plugin-helper.strictParseInt.html +1 -1
  176. package/docs/functions/_saltcorn_data.plugin-testing.auto_test_plugin.html +1 -1
  177. package/docs/functions/_saltcorn_data.plugin-testing.check_view_columns.html +1 -1
  178. package/docs/functions/_saltcorn_data.plugin-testing.generate_attributes.html +1 -1
  179. package/docs/functions/_saltcorn_data.standard-menu.create_standard_menu.html +1 -1
  180. package/docs/functions/_saltcorn_data.tests_assertions.assertIsErrorMsg.html +1 -1
  181. package/docs/functions/_saltcorn_data.tests_assertions.assertIsErrorsMsg.html +1 -1
  182. package/docs/functions/_saltcorn_data.tests_assertions.assertIsRow.html +1 -1
  183. package/docs/functions/_saltcorn_data.tests_assertions.assertIsSet.html +1 -1
  184. package/docs/functions/_saltcorn_data.tests_assertions.assertIsType.html +1 -1
  185. package/docs/functions/_saltcorn_data.tests_assertions.assertsIsSuccessMessage.html +1 -1
  186. package/docs/functions/_saltcorn_data.tests_assertions.assertsObjectIsUser.html +1 -1
  187. package/docs/functions/_saltcorn_data.tests_common_helpers.createAnotherUserField.html +1 -1
  188. package/docs/functions/_saltcorn_data.tests_common_helpers.createKeyFromLevelTwo.html +1 -1
  189. package/docs/functions/_saltcorn_data.tests_common_helpers.createLevelThreeInbound.html +1 -1
  190. package/docs/functions/_saltcorn_data.tests_common_helpers.createMultipleInbounds.html +1 -1
  191. package/docs/functions/_saltcorn_data.tests_common_helpers.createSecondTopicField.html +1 -1
  192. package/docs/functions/_saltcorn_data.tests_common_helpers.prepareEmployeeDepartment.html +1 -1
  193. package/docs/functions/_saltcorn_data.tests_common_helpers.prepareSimpleTopicPostRelation.html +1 -1
  194. package/docs/functions/_saltcorn_data.tests_remote_query_helper.deleteViewFromServer.html +1 -1
  195. package/docs/functions/_saltcorn_data.tests_remote_query_helper.prepareQueryEnviroment.html +1 -1
  196. package/docs/functions/_saltcorn_data.tests_remote_query_helper.sendViewToServer.html +1 -1
  197. package/docs/functions/_saltcorn_data.translate.hasLLM.html +1 -1
  198. package/docs/functions/_saltcorn_data.translate.translate.html +1 -1
  199. package/docs/functions/_saltcorn_db-common.internal.ftsFieldsSqlExpr.html +1 -1
  200. package/docs/functions/_saltcorn_db-common.internal.mkSelectOptions.html +1 -1
  201. package/docs/functions/_saltcorn_db-common.internal.mkWhere.html +1 -1
  202. package/docs/functions/_saltcorn_db-common.internal.orderByIsObject.html +1 -1
  203. package/docs/functions/_saltcorn_db-common.internal.orderByIsOperator.html +1 -1
  204. package/docs/functions/_saltcorn_db-common.internal.prefixFieldsInWhere.html +1 -1
  205. package/docs/functions/_saltcorn_db-common.internal.sqlBinOp.html +1 -1
  206. package/docs/functions/_saltcorn_db-common.internal.sqlFun.html +1 -1
  207. package/docs/functions/_saltcorn_db-common.internal.sqlsanitize.html +1 -1
  208. package/docs/functions/_saltcorn_db-common.internal.sqlsanitizeAllowDots.html +1 -1
  209. package/docs/functions/_saltcorn_db-common.internal.subSelectWhere.html +1 -1
  210. package/docs/functions/_saltcorn_db-common.multi-tenant.enable_multi_tenant.html +1 -1
  211. package/docs/functions/_saltcorn_db-common.multi-tenant.getRequestContext.html +1 -1
  212. package/docs/functions/_saltcorn_db-common.multi-tenant.getTenantSchema.html +1 -1
  213. package/docs/functions/_saltcorn_db-common.multi-tenant.init.html +1 -1
  214. package/docs/functions/_saltcorn_db-common.multi-tenant.is_it_multi_tenant.html +1 -1
  215. package/docs/functions/_saltcorn_db-common.multi-tenant.runWithTenant.html +1 -1
  216. package/docs/functions/_saltcorn_db-common.sqlite-commons.buildInsertBulkSql.html +1 -1
  217. package/docs/functions/_saltcorn_db-common.sqlite-commons.buildInsertSql.html +1 -1
  218. package/docs/functions/_saltcorn_db-common.sqlite-commons.commitAndBeginNewTransaction.html +1 -1
  219. package/docs/functions/_saltcorn_db-common.sqlite-commons.doCount.html +1 -1
  220. package/docs/functions/_saltcorn_db-common.sqlite-commons.doDeleteWhere.html +1 -1
  221. package/docs/functions/_saltcorn_db-common.sqlite-commons.doListScTables.html +1 -1
  222. package/docs/functions/_saltcorn_db-common.sqlite-commons.doListTables.html +1 -1
  223. package/docs/functions/_saltcorn_db-common.sqlite-commons.doListUserDefinedTables.html +1 -1
  224. package/docs/functions/_saltcorn_db-common.sqlite-commons.do_add_index.html +1 -1
  225. package/docs/functions/_saltcorn_db-common.sqlite-commons.do_drop_index.html +1 -1
  226. package/docs/functions/_saltcorn_db-common.sqlite-commons.mkVal.html +1 -1
  227. package/docs/functions/_saltcorn_db-common.sqlite-commons.openOrUseTransaction.html +1 -1
  228. package/docs/functions/_saltcorn_db-common.sqlite-commons.reprAsJson.html +1 -1
  229. package/docs/functions/_saltcorn_db-common.sqlite-commons.slugify.html +1 -1
  230. package/docs/functions/_saltcorn_db-common.sqlite-commons.tryCatchInTransaction.html +1 -1
  231. package/docs/functions/_saltcorn_db-common.sqlite-commons.whenTransactionisFree.html +1 -1
  232. package/docs/functions/_saltcorn_db-common.sqlite-commons.withTransaction.html +1 -1
  233. package/docs/functions/_saltcorn_markup.mktag.mkTag.html +1 -1
  234. package/docs/functions/_saltcorn_markup.tabs.tabs.html +1 -1
  235. package/docs/functions/_saltcorn_markup.workflow.renderWorkflow.html +1 -1
  236. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.androidFeatures.html +1 -1
  237. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.androidPermissions.html +1 -1
  238. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.buildTablesFile.html +1 -1
  239. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.copyPrepopulatedDb.html +1 -1
  240. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.copyServerFiles.html +1 -1
  241. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.copyShareExtFiles.html +1 -1
  242. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.copySiteLogo.html +1 -1
  243. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.copyTranslationFiles.html +1 -1
  244. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.createSqliteDb.html +1 -1
  245. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.extractDomain.html +1 -1
  246. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.generateAndroidVersionCode.html +1 -1
  247. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.hasAuthMethod.html +1 -1
  248. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.modifyAndroidManifest.html +1 -1
  249. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.modifyAppDelegate.html +1 -1
  250. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.modifyConfigXml.html +1 -1
  251. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.modifyGradleConfig.html +1 -1
  252. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.modifyInfoPlist.html +1 -1
  253. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.modifyShareViewController.html +1 -1
  254. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.modifyXcodeProjectFile.html +1 -1
  255. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.prepAppIcon.html +1 -1
  256. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.prepareAppIcon.html +1 -1
  257. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.prepareBuildDir.html +1 -1
  258. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.prepareExportOptionsPlist.html +1 -1
  259. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.prepareSplashIcon.html +1 -1
  260. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.prepareSplashPage.html +1 -1
  261. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.runAddEntitlementsScript.html +1 -1
  262. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.writeCapacitorConfig.html +1 -1
  263. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.writeCfgFile.html +1 -1
  264. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.writeDataExtractionRules.html +1 -1
  265. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.writeEntitlementsPlist.html +1 -1
  266. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.writeNetworkSecurityConfig.html +1 -1
  267. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.writePodfile.html +1 -1
  268. package/docs/functions/_saltcorn_mobile-builder.utils_common-build-utils.writePrivacyInfo.html +1 -1
  269. package/docs/functions/_saltcorn_mobile-builder.utils_package-bundle-utils.bundleMobileAppCode.html +1 -1
  270. package/docs/functions/_saltcorn_mobile-builder.utils_package-bundle-utils.bundlePackagesAndPlugins.html +1 -1
  271. package/docs/functions/_saltcorn_mobile-builder.utils_package-bundle-utils.copyOptionalSource.html +1 -1
  272. package/docs/functions/_saltcorn_mobile-builder.utils_package-bundle-utils.copyPluginMobileAppDirs.html +1 -1
  273. package/docs/functions/_saltcorn_mobile-builder.utils_package-bundle-utils.copyPublicDirs.html +1 -1
  274. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.add_index.html +1 -1
  275. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.add_unique_constraint.html +1 -1
  276. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.count.html +1 -1
  277. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.deleteWhere.html +1 -1
  278. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.drop_index.html +1 -1
  279. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.drop_reset_schema.html +1 -1
  280. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.drop_unique_constraint.html +1 -1
  281. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.init.html +1 -1
  282. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.insert.html +1 -1
  283. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.insertRows.html +1 -1
  284. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.listScTables.html +1 -1
  285. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.listTables.html +1 -1
  286. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.listUserDefinedTables.html +1 -1
  287. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.query.html +1 -1
  288. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.select.html +1 -1
  289. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.selectMaybeOne.html +1 -1
  290. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.selectOne.html +1 -1
  291. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.setConnectionObject.html +1 -1
  292. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.tableExists.html +1 -1
  293. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.time.html +1 -1
  294. package/docs/functions/_saltcorn_sqlite-mobile.sqlite_capacitor.update.html +1 -1
  295. package/docs/functions/_saltcorn_sqlite.sqlite.add_index.html +1 -1
  296. package/docs/functions/_saltcorn_sqlite.sqlite.add_unique_constraint.html +1 -1
  297. package/docs/functions/_saltcorn_sqlite.sqlite.begin.html +1 -1
  298. package/docs/functions/_saltcorn_sqlite.sqlite.changeConnection.html +1 -1
  299. package/docs/functions/_saltcorn_sqlite.sqlite.close.html +1 -1
  300. package/docs/functions/_saltcorn_sqlite.sqlite.commit.html +1 -1
  301. package/docs/functions/_saltcorn_sqlite.sqlite.count.html +1 -1
  302. package/docs/functions/_saltcorn_sqlite.sqlite.deleteWhere.html +1 -1
  303. package/docs/functions/_saltcorn_sqlite.sqlite.dropTable.html +1 -1
  304. package/docs/functions/_saltcorn_sqlite.sqlite.dropTables.html +1 -1
  305. package/docs/functions/_saltcorn_sqlite.sqlite.drop_index.html +1 -1
  306. package/docs/functions/_saltcorn_sqlite.sqlite.drop_reset_schema.html +1 -1
  307. package/docs/functions/_saltcorn_sqlite.sqlite.drop_unique_constraint.html +1 -1
  308. package/docs/functions/_saltcorn_sqlite.sqlite.getVersion.html +1 -1
  309. package/docs/functions/_saltcorn_sqlite.sqlite.get_db_filepath.html +1 -1
  310. package/docs/functions/_saltcorn_sqlite.sqlite.get_sql_logging.html +1 -1
  311. package/docs/functions/_saltcorn_sqlite.sqlite.init.html +1 -1
  312. package/docs/functions/_saltcorn_sqlite.sqlite.insert.html +1 -1
  313. package/docs/functions/_saltcorn_sqlite.sqlite.listScTables.html +1 -1
  314. package/docs/functions/_saltcorn_sqlite.sqlite.listTables.html +1 -1
  315. package/docs/functions/_saltcorn_sqlite.sqlite.listUserDefinedTables.html +1 -1
  316. package/docs/functions/_saltcorn_sqlite.sqlite.query.html +1 -1
  317. package/docs/functions/_saltcorn_sqlite.sqlite.rollback.html +1 -1
  318. package/docs/functions/_saltcorn_sqlite.sqlite.select.html +1 -1
  319. package/docs/functions/_saltcorn_sqlite.sqlite.selectMaybeOne.html +1 -1
  320. package/docs/functions/_saltcorn_sqlite.sqlite.selectOne.html +1 -1
  321. package/docs/functions/_saltcorn_sqlite.sqlite.set_sql_logging.html +1 -1
  322. package/docs/functions/_saltcorn_sqlite.sqlite.sql_log.html +1 -1
  323. package/docs/functions/_saltcorn_sqlite.sqlite.update.html +1 -1
  324. package/docs/functions/_saltcorn_sqlite.sqlite.updateWhere.html +1 -1
  325. package/docs/functions/_saltcorn_types.base_types.instanceOWithHtmlFile.html +1 -1
  326. package/docs/functions/_saltcorn_types.base_types.instanceOfFieldViewEdit.html +1 -1
  327. package/docs/functions/_saltcorn_types.base_types.instanceOfFieldViewShow.html +1 -1
  328. package/docs/functions/_saltcorn_types.base_types.instanceOfPack.html +1 -1
  329. package/docs/functions/_saltcorn_types.common_types.instanceOfErrorMsg.html +1 -1
  330. package/docs/functions/_saltcorn_types.common_types.instanceOfSuccessMsg.html +1 -1
  331. package/docs/functions/_saltcorn_types.common_types.instanceOfType.html +1 -1
  332. package/docs/functions/_saltcorn_types.model-abstracts_abstract_field.instanceOfField.html +1 -1
  333. package/docs/functions/_saltcorn_types.model-abstracts_abstract_page.instanceOfPage.html +1 -1
  334. package/docs/functions/_saltcorn_types.model-abstracts_abstract_plugin.instanceOfPlugin.html +1 -1
  335. package/docs/functions/_saltcorn_types.model-abstracts_abstract_table.instanceOfTable.html +1 -1
  336. package/docs/functions/_saltcorn_types.model-abstracts_abstract_view.instanceOfView.html +1 -1
  337. package/docs/hierarchy.html +1 -1
  338. package/docs/interfaces/_saltcorn_db-common.dbtypes.UserLike.html +2 -2
  339. package/docs/interfaces/_saltcorn_markup.types.TagExports.html +2 -2
  340. package/docs/interfaces/_saltcorn_mobile-builder.utils_common-build-utils.ScCapacitorConfig.html +2 -2
  341. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_field.AbstractField.html +2 -2
  342. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_field.AbstractFieldRepeat.html +2 -2
  343. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_form.AbstractForm.html +2 -2
  344. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_page.AbstractPage.html +2 -2
  345. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_page_group.AbstractPageGroup.html +2 -2
  346. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_page_group_member.AbstractPageGroupMember.html +2 -2
  347. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_plugin.AbstractPlugin.html +2 -2
  348. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_role.AbstractRole.html +2 -2
  349. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_table.AbstractTable.html +2 -2
  350. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_tag.AbstractTag.html +2 -2
  351. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_tag_entry.AbstractTagEntry.html +2 -2
  352. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_trigger.AbstractTrigger.html +2 -2
  353. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_user.AbstractUser.html +2 -2
  354. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_user.ForUserRequest.html +2 -2
  355. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_view.AbstractView.html +2 -2
  356. package/docs/interfaces/_saltcorn_types.model-abstracts_abstract_workflow.AbstractWorkflow.html +2 -2
  357. package/docs/modules/_saltcorn_data.html +1 -1
  358. package/docs/modules/_saltcorn_data.migrations_202604091531.html +1 -0
  359. package/docs/modules/_saltcorn_data.migrations_202604111200.html +1 -0
  360. package/docs/modules/_saltcorn_data.migrations_202604141200.html +1 -0
  361. package/docs/modules/_saltcorn_data.mobile-mocks_node_fs.html +1 -1
  362. package/docs/modules/_saltcorn_data.mobile-mocks_node_fs_promises.html +1 -1
  363. package/docs/modules/_saltcorn_data.mobile-mocks_npm_npm-registry-fetch.html +1 -0
  364. package/docs/modules/_saltcorn_data.mobile-mocks_saltcorn_admin-models-tenant.html +1 -0
  365. package/docs/modules/_saltcorn_data.mobile-mocks_saltcorn_plugins-loader-plugin-installer.html +1 -0
  366. package/docs/modules/_saltcorn_data.mobile-mocks_saltcorn_plugins-loader-stable-versioning.html +1 -0
  367. package/docs/modules/_saltcorn_data.models_index.discovery.html +1 -1
  368. package/docs/types/_saltcorn_data.diagram_node_extract_utils.ExtractOpts.html +2 -2
  369. package/docs/types/_saltcorn_data.diagram_node_extract_utils.ExtractResult.html +2 -2
  370. package/docs/types/_saltcorn_data.diagram_nodes_node.NodeType.html +1 -1
  371. package/docs/types/_saltcorn_data.models_config.ConfigTypes.html +1 -1
  372. package/docs/types/_saltcorn_data.models_config.SingleConfig.html +1 -1
  373. package/docs/types/_saltcorn_data.models_eventlog.EventLogCfg.html +2 -2
  374. package/docs/types/_saltcorn_data.models_file.FileCfg.html +2 -2
  375. package/docs/types/_saltcorn_data.models_form.AdditionalButton.html +1 -1
  376. package/docs/types/_saltcorn_data.models_form.FormCfg.html +2 -2
  377. package/docs/types/_saltcorn_data.models_internal_push_message_helper.MobileSubscription.html +2 -2
  378. package/docs/types/_saltcorn_data.models_internal_push_message_helper.WebPushSubscription.html +2 -2
  379. package/docs/types/_saltcorn_data.models_internal_s3_helpers.S3HeadResult.html +1 -1
  380. package/docs/types/_saltcorn_data.models_internal_s3_helpers.S3ListResult.html +2 -2
  381. package/docs/types/_saltcorn_data.models_page_group.ScreenInfoParams.html +2 -2
  382. package/docs/types/_saltcorn_data.models_table.ChildRelations.html +2 -2
  383. package/docs/types/_saltcorn_data.models_table.ParentRelations.html +2 -2
  384. package/docs/types/_saltcorn_data.models_table.RelationData.html +2 -2
  385. package/docs/types/_saltcorn_data.models_tag_entry.TagEntryCfg.html +1 -1
  386. package/docs/types/_saltcorn_data.models_view.FindViewsPred.html +1 -1
  387. package/docs/types/_saltcorn_db-common.dbtypes.AggregationOptions.html +2 -2
  388. package/docs/types/_saltcorn_db-common.dbtypes.CoordOpts.html +2 -2
  389. package/docs/types/_saltcorn_db-common.dbtypes.DatabaseClient.html +2 -2
  390. package/docs/types/_saltcorn_db-common.dbtypes.JoinField.html +2 -2
  391. package/docs/types/_saltcorn_db-common.dbtypes.JoinFields.html +1 -1
  392. package/docs/types/_saltcorn_db-common.dbtypes.JoinOptions.html +1 -1
  393. package/docs/types/_saltcorn_db-common.dbtypes.JsonPath.html +1 -1
  394. package/docs/types/_saltcorn_db-common.dbtypes.JsonPathElem.html +1 -1
  395. package/docs/types/_saltcorn_db-common.dbtypes.Operator.html +1 -1
  396. package/docs/types/_saltcorn_db-common.dbtypes.PartialSome.html +1 -1
  397. package/docs/types/_saltcorn_db-common.dbtypes.PrimaryKeyValue.html +1 -1
  398. package/docs/types/_saltcorn_db-common.dbtypes.Row.html +1 -1
  399. package/docs/types/_saltcorn_db-common.dbtypes.SelectOptions.html +2 -2
  400. package/docs/types/_saltcorn_db-common.dbtypes.StrongRow.html +1 -1
  401. package/docs/types/_saltcorn_db-common.dbtypes.SubselectOptions.html +2 -2
  402. package/docs/types/_saltcorn_db-common.dbtypes.Value.html +1 -1
  403. package/docs/types/_saltcorn_db-common.dbtypes.Where.html +2 -2
  404. package/docs/types/_saltcorn_db-common.sqlite-commons.SqlAndValues.html +2 -2
  405. package/docs/types/_saltcorn_db-common.types.DbExportsType.html +2 -2
  406. package/docs/types/_saltcorn_db-common.types.GenObj.html +1 -1
  407. package/docs/types/_saltcorn_markup.emergency_layout.WrapParams.html +2 -2
  408. package/docs/types/_saltcorn_markup.helpers.CheckBoxGroupOpts.html +2 -2
  409. package/docs/types/_saltcorn_markup.helpers.PaginationOpts.html +2 -2
  410. package/docs/types/_saltcorn_markup.helpers.RadioGroupOpts.html +2 -2
  411. package/docs/types/_saltcorn_markup.helpers.SearchBarOpts.html +2 -2
  412. package/docs/types/_saltcorn_markup.layout.RenderOpts-1.html +2 -2
  413. package/docs/types/_saltcorn_markup.layout.RenderOpts.html +2 -2
  414. package/docs/types/_saltcorn_markup.mjml-layout.RenderOpts.html +2 -2
  415. package/docs/types/_saltcorn_markup.table.HeadersParams.html +2 -2
  416. package/docs/types/_saltcorn_markup.table.OptsParams.html +2 -2
  417. package/docs/types/_saltcorn_markup.types.AttributeVal.html +1 -1
  418. package/docs/types/_saltcorn_markup.types.Attributes.html +2 -2
  419. package/docs/types/_saltcorn_markup.types.ClassVal.html +1 -1
  420. package/docs/types/_saltcorn_markup.types.Element.html +1 -1
  421. package/docs/types/_saltcorn_markup.types.Falsy.html +1 -1
  422. package/docs/types/_saltcorn_markup.types.StyleVal.html +1 -1
  423. package/docs/types/_saltcorn_markup.types.TagFunction.html +1 -1
  424. package/docs/types/_saltcorn_mobile-builder.mobile-builder.IosCfg.html +2 -2
  425. package/docs/types/_saltcorn_mobile-builder.utils_capacitor-helper.CapacitorCfg.html +2 -2
  426. package/docs/types/_saltcorn_types.base_types.Action.html +5 -4
  427. package/docs/types/_saltcorn_types.base_types.AuthenticationMethod.html +2 -2
  428. package/docs/types/_saltcorn_types.base_types.CalcJoinfield.html +2 -2
  429. package/docs/types/_saltcorn_types.base_types.CapacitorPlugin.html +2 -2
  430. package/docs/types/_saltcorn_types.base_types.CodePagePack.html +2 -2
  431. package/docs/types/_saltcorn_types.base_types.Column.html +2 -2
  432. package/docs/types/_saltcorn_types.base_types.ConnectObjType.html +2 -2
  433. package/docs/types/_saltcorn_types.base_types.ConnectedObjects.html +2 -2
  434. package/docs/types/_saltcorn_types.base_types.CopilotSkill.html +2 -2
  435. package/docs/types/_saltcorn_types.base_types.ErrorObj.html +2 -2
  436. package/docs/types/_saltcorn_types.base_types.FieldLike.html +1 -1
  437. package/docs/types/_saltcorn_types.base_types.FieldView.html +1 -1
  438. package/docs/types/_saltcorn_types.base_types.Header.html +2 -2
  439. package/docs/types/_saltcorn_types.base_types.JoinFieldOption.html +2 -2
  440. package/docs/types/_saltcorn_types.base_types.Layout.html +1 -1
  441. package/docs/types/_saltcorn_types.base_types.MenuItem.html +2 -2
  442. package/docs/types/_saltcorn_types.base_types.MobileConfig.html +2 -3
  443. package/docs/types/_saltcorn_types.base_types.ModelPattern.html +6 -6
  444. package/docs/types/_saltcorn_types.base_types.Pack.html +2 -2
  445. package/docs/types/_saltcorn_types.base_types.Plugin.html +1 -1
  446. package/docs/types/_saltcorn_types.base_types.PluginFunction.html +3 -2
  447. package/docs/types/_saltcorn_types.base_types.PluginLayout.html +2 -2
  448. package/docs/types/_saltcorn_types.base_types.PluginRoute.html +2 -2
  449. package/docs/types/_saltcorn_types.base_types.PluginSourceType.html +1 -1
  450. package/docs/types/_saltcorn_types.base_types.PluginType.html +2 -2
  451. package/docs/types/_saltcorn_types.base_types.PluginWrap.html +1 -1
  452. package/docs/types/_saltcorn_types.base_types.PluginWrapArg.html +2 -2
  453. package/docs/types/_saltcorn_types.base_types.RelationOption.html +2 -2
  454. package/docs/types/_saltcorn_types.base_types.Req.html +2 -2
  455. package/docs/types/_saltcorn_types.base_types.Res.html +2 -2
  456. package/docs/types/_saltcorn_types.base_types.ResultType.html +2 -2
  457. package/docs/types/_saltcorn_types.base_types.RouteAction.html +1 -1
  458. package/docs/types/_saltcorn_types.base_types.RunExtra.html +1 -1
  459. package/docs/types/_saltcorn_types.base_types.SlugStepType.html +2 -2
  460. package/docs/types/_saltcorn_types.base_types.StepResType.html +1 -1
  461. package/docs/types/_saltcorn_types.base_types.SubField.html +2 -2
  462. package/docs/types/_saltcorn_types.base_types.TableProvider.html +2 -2
  463. package/docs/types/_saltcorn_types.base_types.TableQuery.html +2 -2
  464. package/docs/types/_saltcorn_types.base_types.Tablely.html +1 -1
  465. package/docs/types/_saltcorn_types.base_types.ViewTemplate.html +3 -2
  466. package/docs/types/_saltcorn_types.common_types.ErrorMessage.html +2 -2
  467. package/docs/types/_saltcorn_types.common_types.GenObj.html +1 -1
  468. package/docs/types/_saltcorn_types.common_types.ReqRes.html +2 -2
  469. package/docs/types/_saltcorn_types.common_types.ResultMessage.html +1 -1
  470. package/docs/types/_saltcorn_types.common_types.SuccessMessage.html +2 -2
  471. package/docs/types/_saltcorn_types.common_types.Type.html +2 -2
  472. package/docs/types/_saltcorn_types.model-abstracts_abstract_event_log.EventLogPack.html +2 -2
  473. package/docs/types/_saltcorn_types.model-abstracts_abstract_field.FieldCfg.html +2 -2
  474. package/docs/types/_saltcorn_types.model-abstracts_abstract_field.InputType.html +1 -1
  475. package/docs/types/_saltcorn_types.model-abstracts_abstract_form.AdditionalButton.html +2 -2
  476. package/docs/types/_saltcorn_types.model-abstracts_abstract_library.LibraryCfg.html +2 -2
  477. package/docs/types/_saltcorn_types.model-abstracts_abstract_library.LibraryPack.html +1 -1
  478. package/docs/types/_saltcorn_types.model-abstracts_abstract_model.ModelCfg.html +2 -2
  479. package/docs/types/_saltcorn_types.model-abstracts_abstract_model.ModelPack.html +1 -1
  480. package/docs/types/_saltcorn_types.model-abstracts_abstract_model_instance.ModelInstanceCfg.html +2 -2
  481. package/docs/types/_saltcorn_types.model-abstracts_abstract_model_instance.ModelInstancePack.html +1 -1
  482. package/docs/types/_saltcorn_types.model-abstracts_abstract_page.PageCfg.html +3 -2
  483. package/docs/types/_saltcorn_types.model-abstracts_abstract_page.PagePack.html +1 -1
  484. package/docs/types/_saltcorn_types.model-abstracts_abstract_page_group.PageGroupCfg.html +2 -2
  485. package/docs/types/_saltcorn_types.model-abstracts_abstract_page_group.PageGroupPack.html +1 -1
  486. package/docs/types/_saltcorn_types.model-abstracts_abstract_page_group_member.PageGroupMemberCfg.html +2 -2
  487. package/docs/types/_saltcorn_types.model-abstracts_abstract_page_group_member.PageGroupMemberPack.html +1 -1
  488. package/docs/types/_saltcorn_types.model-abstracts_abstract_plugin.PluginCfg.html +3 -2
  489. package/docs/types/_saltcorn_types.model-abstracts_abstract_plugin.PluginPack.html +1 -1
  490. package/docs/types/_saltcorn_types.model-abstracts_abstract_role.RoleCfg.html +1 -1
  491. package/docs/types/_saltcorn_types.model-abstracts_abstract_role.RolePack.html +1 -1
  492. package/docs/types/_saltcorn_types.model-abstracts_abstract_table.TableCfg.html +3 -2
  493. package/docs/types/_saltcorn_types.model-abstracts_abstract_table.TablePack.html +1 -1
  494. package/docs/types/_saltcorn_types.model-abstracts_abstract_tag.TagPack.html +2 -2
  495. package/docs/types/_saltcorn_types.model-abstracts_abstract_tag_entry.TagEntryPack.html +2 -2
  496. package/docs/types/_saltcorn_types.model-abstracts_abstract_trigger.TriggerCfg.html +3 -2
  497. package/docs/types/_saltcorn_types.model-abstracts_abstract_trigger.TriggerPack.html +1 -1
  498. package/docs/types/_saltcorn_types.model-abstracts_abstract_view.ViewCfg.html +3 -2
  499. package/docs/types/_saltcorn_types.model-abstracts_abstract_view.ViewPack.html +1 -1
  500. package/docs/types/_saltcorn_types.model-abstracts_abstract_workflow.ConfigWorkflowStep.html +1 -1
  501. package/docs/types/_saltcorn_types.model-abstracts_abstract_workflow.RunResult.html +2 -2
  502. package/docs/types/_saltcorn_types.model-abstracts_abstract_workflow_run.WorkflowRunCfg.html +2 -2
  503. package/docs/types/_saltcorn_types.model-abstracts_abstract_workflow_step.WorkflowStepCfg.html +2 -2
  504. package/docs/types/_saltcorn_types.model-abstracts_abstract_workflow_step.WorkflowStepPack.html +1 -1
  505. package/docs/types/_saltcorn_types.model-abstracts_abstract_workflow_trace.WorkflowTraceCfg.html +2 -2
  506. package/docs/variables/_saltcorn_admin-models..backup.create_backup.html +1 -1
  507. package/docs/variables/_saltcorn_admin-models..backup.create_csv_from_rows.html +1 -1
  508. package/docs/variables/_saltcorn_admin-models..backup.restore.html +1 -1
  509. package/docs/variables/_saltcorn_admin-models..pack.add_to_menu.html +1 -1
  510. package/docs/variables/_saltcorn_admin-models..pack.can_install_pack.html +1 -1
  511. package/docs/variables/_saltcorn_admin-models..pack.fetch_available_packs.html +1 -1
  512. package/docs/variables/_saltcorn_admin-models..pack.fetch_pack_by_name.html +1 -1
  513. package/docs/variables/_saltcorn_admin-models..pack.install_pack.html +1 -1
  514. package/docs/variables/_saltcorn_admin-models..pack.library_pack.html +1 -1
  515. package/docs/variables/_saltcorn_admin-models..pack.model_instance_pack.html +1 -1
  516. package/docs/variables/_saltcorn_admin-models..pack.model_pack.html +1 -1
  517. package/docs/variables/_saltcorn_admin-models..pack.page_group_pack.html +1 -1
  518. package/docs/variables/_saltcorn_admin-models..pack.page_pack.html +1 -1
  519. package/docs/variables/_saltcorn_admin-models..pack.plugin_pack.html +1 -1
  520. package/docs/variables/_saltcorn_admin-models..pack.role_pack.html +1 -1
  521. package/docs/variables/_saltcorn_admin-models..pack.table_pack.html +1 -1
  522. package/docs/variables/_saltcorn_admin-models..pack.trigger_pack.html +1 -1
  523. package/docs/variables/_saltcorn_admin-models..pack.uninstall_pack.html +1 -1
  524. package/docs/variables/_saltcorn_admin-models..pack.view_pack.html +1 -1
  525. package/docs/variables/_saltcorn_admin-models..tenant.copy_tenant_template.html +1 -1
  526. package/docs/variables/_saltcorn_admin-models..tenant.create_tenant.html +1 -1
  527. package/docs/variables/_saltcorn_admin-models..tenant.deleteTenant.html +1 -1
  528. package/docs/variables/_saltcorn_admin-models..tenant.domain_sanitize.html +1 -1
  529. package/docs/variables/_saltcorn_admin-models..tenant.eachTenant.html +1 -1
  530. package/docs/variables/_saltcorn_admin-models..tenant.getAllTenantRows.html +1 -1
  531. package/docs/variables/_saltcorn_admin-models..tenant.getAllTenants.html +1 -1
  532. package/docs/variables/_saltcorn_admin-models..tenant.insertTenant.html +1 -1
  533. package/docs/variables/_saltcorn_admin-models..tenant.switchToTenant.html +1 -1
  534. package/docs/variables/_saltcorn_admin-models.models_backup.backup.html +1 -1
  535. package/docs/variables/_saltcorn_admin-models.pack.pack.html +1 -1
  536. package/docs/variables/_saltcorn_admin-models.tenant.tenant.html +1 -1
  537. package/docs/variables/_saltcorn_common-code.tests_expected_relations.expectedFive.html +1 -1
  538. package/docs/variables/_saltcorn_common-code.tests_expected_relations.expectedFour.html +1 -1
  539. package/docs/variables/_saltcorn_common-code.tests_expected_relations.expectedOne.html +1 -1
  540. package/docs/variables/_saltcorn_common-code.tests_expected_relations.expectedSix.html +1 -1
  541. package/docs/variables/_saltcorn_common-code.tests_expected_relations.expectedThree.html +1 -1
  542. package/docs/variables/_saltcorn_common-code.tests_expected_relations.expectedTwo.html +1 -1
  543. package/docs/variables/_saltcorn_data..migrations.html +1 -1
  544. package/docs/variables/_saltcorn_data..plugin_helper.run_action_column.html +1 -1
  545. package/docs/variables/_saltcorn_data..utils.NotAuthorized.html +1 -1
  546. package/docs/variables/_saltcorn_data..utils.isPushEnabled.html +1 -1
  547. package/docs/variables/_saltcorn_data..utils.sleep.html +1 -1
  548. package/docs/variables/_saltcorn_data.base-plugin_actions.actions.html +13 -13
  549. package/docs/variables/_saltcorn_data.base-plugin_fieldviews.fieldviews.html +3 -3
  550. package/docs/variables/_saltcorn_data.base-plugin_fileview.fileviews.html +1 -1
  551. package/docs/variables/_saltcorn_data.base-plugin_index.index.html +15 -15
  552. package/docs/variables/_saltcorn_data.base-plugin_types.types.html +7 -7
  553. package/docs/variables/_saltcorn_data.base-plugin_viewtemplates_edit.edit.html +1 -1
  554. package/docs/variables/_saltcorn_data.base-plugin_viewtemplates_feed.feed.html +1 -1
  555. package/docs/variables/_saltcorn_data.base-plugin_viewtemplates_filter.filter.html +1 -1
  556. package/docs/variables/_saltcorn_data.base-plugin_viewtemplates_list.list.html +1 -1
  557. package/docs/variables/_saltcorn_data.base-plugin_viewtemplates_listshowlist.listshowlist.html +1 -1
  558. package/docs/variables/_saltcorn_data.base-plugin_viewtemplates_room.room-1.html +1 -1
  559. package/docs/variables/_saltcorn_data.base-plugin_viewtemplates_room.room.html +1 -1
  560. package/docs/variables/_saltcorn_data.base-plugin_viewtemplates_show.show.html +1 -1
  561. package/docs/variables/_saltcorn_data.base-plugin_viewtemplates_viewable_fields.edit_build_in_actions.html +1 -1
  562. package/docs/variables/_saltcorn_data.contract.contract.html +1 -1
  563. package/docs/variables/_saltcorn_data.db_connect.connect.html +1 -1
  564. package/docs/variables/_saltcorn_data.db_fa5-icons.fa5Icons.html +1 -1
  565. package/docs/variables/_saltcorn_data.db_fixtures.fixtures.html +1 -1
  566. package/docs/variables/_saltcorn_data.db_index.dbExports.html +1 -1
  567. package/docs/variables/_saltcorn_data.db_state.state.html +3 -3
  568. package/docs/variables/_saltcorn_data.migrations_202005141503.sql.html +1 -1
  569. package/docs/variables/_saltcorn_data.migrations_202005241712.sql.html +1 -1
  570. package/docs/variables/_saltcorn_data.migrations_202005251037.sql.html +1 -1
  571. package/docs/variables/_saltcorn_data.migrations_202005282134.sql.html +1 -1
  572. package/docs/variables/_saltcorn_data.migrations_202006022156.sql.html +1 -1
  573. package/docs/variables/_saltcorn_data.migrations_202006051507.sql.html +1 -1
  574. package/docs/variables/_saltcorn_data.migrations_202006240906.sql.html +1 -1
  575. package/docs/variables/_saltcorn_data.migrations_202007091707.sql.html +1 -1
  576. package/docs/variables/_saltcorn_data.migrations_202007202144.sql.html +1 -1
  577. package/docs/variables/_saltcorn_data.migrations_202008031500.sql.html +1 -1
  578. package/docs/variables/_saltcorn_data.migrations_202008051415.sql.html +1 -1
  579. package/docs/variables/_saltcorn_data.migrations_202008121149.sql_pg.html +1 -1
  580. package/docs/variables/_saltcorn_data.migrations_202008121149.sql_sqlite.html +1 -1
  581. package/docs/variables/_saltcorn_data.migrations_202009112140.sql_pg.html +1 -1
  582. package/docs/variables/_saltcorn_data.migrations_202009112140.sql_sqlite.html +1 -1
  583. package/docs/variables/_saltcorn_data.migrations_202009181655.sql.html +1 -1
  584. package/docs/variables/_saltcorn_data.migrations_202009221105.sql.html +1 -1
  585. package/docs/variables/_saltcorn_data.migrations_202009231331.sql.html +1 -1
  586. package/docs/variables/_saltcorn_data.migrations_202009301531.sql.html +1 -1
  587. package/docs/variables/_saltcorn_data.migrations_202010231444.sql.html +1 -1
  588. package/docs/variables/_saltcorn_data.migrations_202010251412.sql.html +1 -1
  589. package/docs/variables/_saltcorn_data.migrations_202011021749.sql.html +1 -1
  590. package/docs/variables/_saltcorn_data.migrations_202011051353.sql.html +1 -1
  591. package/docs/variables/_saltcorn_data.migrations_202011111127.sql.html +1 -1
  592. package/docs/variables/_saltcorn_data.migrations_202012011203.sql.html +1 -1
  593. package/docs/variables/_saltcorn_data.migrations_202012100841.sql.html +1 -1
  594. package/docs/variables/_saltcorn_data.migrations_202012281835.sql.html +1 -1
  595. package/docs/variables/_saltcorn_data.migrations_202101061051.sql.html +1 -1
  596. package/docs/variables/_saltcorn_data.migrations_202101141128.sql.html +1 -1
  597. package/docs/variables/_saltcorn_data.migrations_202102091312.sql.html +1 -1
  598. package/docs/variables/_saltcorn_data.migrations_202102101624.sql.html +1 -1
  599. package/docs/variables/_saltcorn_data.migrations_202102172148.sql.html +1 -1
  600. package/docs/variables/_saltcorn_data.migrations_202102261650.sql.html +1 -1
  601. package/docs/variables/_saltcorn_data.migrations_202106102347.sql.html +1 -1
  602. package/docs/variables/_saltcorn_data.migrations_202106112120.sql.html +1 -1
  603. package/docs/variables/_saltcorn_data.migrations_202106120012.sql.html +1 -1
  604. package/docs/variables/_saltcorn_data.migrations_202106120220.sql.html +1 -1
  605. package/docs/variables/_saltcorn_data.migrations_202106121701.sql.html +1 -1
  606. package/docs/variables/_saltcorn_data.migrations_202106121703.sql_pg.html +1 -1
  607. package/docs/variables/_saltcorn_data.migrations_202106121703.sql_sqlite.html +1 -1
  608. package/docs/variables/_saltcorn_data.migrations_202106251126.sql.html +1 -1
  609. package/docs/variables/_saltcorn_data.migrations_202107281619.sql.html +1 -1
  610. package/docs/variables/_saltcorn_data.migrations_202107302158.sql_pg.html +1 -1
  611. package/docs/variables/_saltcorn_data.migrations_202107302158.sql_sqlite.html +1 -1
  612. package/docs/variables/_saltcorn_data.migrations_202108022257.sql.html +1 -1
  613. package/docs/variables/_saltcorn_data.migrations_202109201624.sql.html +1 -1
  614. package/docs/variables/_saltcorn_data.migrations_202109301031.sql_pg.html +1 -1
  615. package/docs/variables/_saltcorn_data.migrations_202109301031.sql_sqlite.html +1 -1
  616. package/docs/variables/_saltcorn_data.migrations_202111290253.sql_pg.html +1 -1
  617. package/docs/variables/_saltcorn_data.migrations_202111290253.sql_sqlite.html +1 -1
  618. package/docs/variables/_saltcorn_data.migrations_202112282254.sql_pg.html +1 -1
  619. package/docs/variables/_saltcorn_data.migrations_202112282254.sql_sqlite.html +1 -1
  620. package/docs/variables/_saltcorn_data.migrations_202207022002.sql.html +1 -1
  621. package/docs/variables/_saltcorn_data.migrations_202207252150.sql_pg.html +1 -1
  622. package/docs/variables/_saltcorn_data.migrations_202207252150.sql_sqlite.html +1 -1
  623. package/docs/variables/_saltcorn_data.migrations_202207261221.sql.html +1 -1
  624. package/docs/variables/_saltcorn_data.migrations_202208101144.sql_pg.html +1 -1
  625. package/docs/variables/_saltcorn_data.migrations_202208101144.sql_sqlite.html +1 -1
  626. package/docs/variables/_saltcorn_data.migrations_202211040031.sql.html +1 -1
  627. package/docs/variables/_saltcorn_data.migrations_202212112152.sql_pg.html +1 -1
  628. package/docs/variables/_saltcorn_data.migrations_202212112152.sql_sqlite.html +1 -1
  629. package/docs/variables/_saltcorn_data.migrations_202301130917.sql.html +1 -1
  630. package/docs/variables/_saltcorn_data.migrations_202303201126.sql_pg.html +1 -1
  631. package/docs/variables/_saltcorn_data.migrations_202303201126.sql_sqlite.html +1 -1
  632. package/docs/variables/_saltcorn_data.migrations_202303221944.sql_pg.html +1 -1
  633. package/docs/variables/_saltcorn_data.migrations_202303221944.sql_sqlite.html +1 -1
  634. package/docs/variables/_saltcorn_data.migrations_202304281224.sql.html +1 -1
  635. package/docs/variables/_saltcorn_data.migrations_202305031518.sql_pg.html +1 -1
  636. package/docs/variables/_saltcorn_data.migrations_202305031518.sql_sqlite.html +1 -1
  637. package/docs/variables/_saltcorn_data.migrations_202308211648.sql.html +1 -1
  638. package/docs/variables/_saltcorn_data.migrations_202311011755.sql_pg.html +1 -1
  639. package/docs/variables/_saltcorn_data.migrations_202311011755.sql_sqlite.html +1 -1
  640. package/docs/variables/_saltcorn_data.migrations_202311231356.sql.html +1 -1
  641. package/docs/variables/_saltcorn_data.migrations_202402071125.sql.html +1 -1
  642. package/docs/variables/_saltcorn_data.migrations_202406260915.sql.html +1 -1
  643. package/docs/variables/_saltcorn_data.migrations_202412051957.sql_pg.html +1 -1
  644. package/docs/variables/_saltcorn_data.migrations_202412051957.sql_sqlite.html +1 -1
  645. package/docs/variables/_saltcorn_data.migrations_202412111526.sql_pg.html +1 -1
  646. package/docs/variables/_saltcorn_data.migrations_202412111526.sql_sqlite.html +1 -1
  647. package/docs/variables/_saltcorn_data.migrations_202501081226.sql_pg.html +1 -1
  648. package/docs/variables/_saltcorn_data.migrations_202501081226.sql_sqlite.html +1 -1
  649. package/docs/variables/_saltcorn_data.migrations_202501201239.sql_sqlite.html +1 -1
  650. package/docs/variables/_saltcorn_data.migrations_202501262157.sql.html +1 -1
  651. package/docs/variables/_saltcorn_data.migrations_202503071353.sql_pg.html +1 -1
  652. package/docs/variables/_saltcorn_data.migrations_202506050958.sql.html +1 -1
  653. package/docs/variables/_saltcorn_data.migrations_202510110312.sql_pg.html +1 -1
  654. package/docs/variables/_saltcorn_data.migrations_202510110312.sql_sqlite.html +1 -1
  655. package/docs/variables/_saltcorn_data.migrations_202511081024.sql.html +1 -1
  656. package/docs/variables/_saltcorn_data.migrations_202604091531.sql.html +1 -0
  657. package/docs/variables/_saltcorn_data.mobile-mocks_npm_npm-registry-fetch.npmRegistryFetch.html +1 -0
  658. package/docs/variables/_saltcorn_data.mobile-mocks_saltcorn_html-pdf-node.htmlPdfNode.html +1 -1
  659. package/docs/variables/_saltcorn_data.models_config.configExports.html +1 -1
  660. package/docs/variables/_saltcorn_data.models_discovery.discovery.html +6 -2
  661. package/docs/variables/_saltcorn_data.models_email.email.html +3 -3
  662. package/docs/variables/_saltcorn_data.models_expression.expression.html +3 -3
  663. package/docs/variables/_saltcorn_data.models_index.config.available_languages.html +1 -1
  664. package/docs/variables/_saltcorn_data.models_index.config.check_email_mask.html +1 -1
  665. package/docs/variables/_saltcorn_data.models_index.config.configTypes.html +1 -1
  666. package/docs/variables/_saltcorn_data.models_index.config.deleteConfig.html +1 -1
  667. package/docs/variables/_saltcorn_data.models_index.config.getAllConfig.html +1 -1
  668. package/docs/variables/_saltcorn_data.models_index.config.getConfig.html +1 -1
  669. package/docs/variables/_saltcorn_data.models_index.config.get_base_url.html +1 -1
  670. package/docs/variables/_saltcorn_data.models_index.config.get_latest_npm_version.html +1 -1
  671. package/docs/variables/_saltcorn_data.models_index.config.remove_from_menu.html +1 -1
  672. package/docs/variables/_saltcorn_data.models_index.config.save_menu_items.html +1 -1
  673. package/docs/variables/_saltcorn_data.models_index.config.setConfig.html +1 -1
  674. package/docs/variables/_saltcorn_data.models_index.discovery.discover_tables.html +1 -1
  675. package/docs/variables/_saltcorn_data.models_index.discovery.discoverable_tables.html +1 -1
  676. package/docs/variables/_saltcorn_data.models_index.discovery.findType.html +1 -1
  677. package/docs/variables/_saltcorn_data.models_index.discovery.get_existing_views.html +1 -1
  678. package/docs/variables/_saltcorn_data.models_index.discovery.implement_discovery.html +1 -1
  679. package/docs/variables/_saltcorn_data.models_index.discovery.make_field.html +1 -0
  680. package/docs/variables/_saltcorn_data.models_index.discovery.reconcile_table.html +7 -0
  681. package/docs/variables/_saltcorn_data.models_index.email.getMailTransport.html +1 -1
  682. package/docs/variables/_saltcorn_data.models_index.email.send_verification_email.html +1 -1
  683. package/docs/variables/_saltcorn_data.models_index.email.viewToEmailHtml.html +1 -1
  684. package/docs/variables/_saltcorn_data.models_index.expression.apply_calculated_fields.html +1 -1
  685. package/docs/variables/_saltcorn_data.models_index.expression.apply_calculated_fields_stored.html +1 -1
  686. package/docs/variables/_saltcorn_data.models_index.expression.eval_expression.html +9 -1
  687. package/docs/variables/_saltcorn_data.models_index.expression.expressionValidator.html +1 -1
  688. package/docs/variables/_saltcorn_data.models_index.expression.get_async_expression_function.html +1 -1
  689. package/docs/variables/_saltcorn_data.models_index.expression.get_expression_function.html +1 -1
  690. package/docs/variables/_saltcorn_data.models_index.expression.jsexprToWhere.html +1 -1
  691. package/docs/variables/_saltcorn_data.models_index.expression.recalculate_for_stored.html +1 -1
  692. package/docs/variables/_saltcorn_data.models_index.expression.transform_for_async.html +1 -1
  693. package/docs/variables/_saltcorn_data.models_index.layout.eachView.html +1 -1
  694. package/docs/variables/_saltcorn_data.models_index.layout.getStringsForI18n.html +1 -1
  695. package/docs/variables/_saltcorn_data.models_index.layout.getViews.html +1 -1
  696. package/docs/variables/_saltcorn_data.models_index.layout.translateLayout.html +1 -1
  697. package/docs/variables/_saltcorn_data.models_index.layout.traverse.html +1 -1
  698. package/docs/variables/_saltcorn_data.models_index.layout.traverseSync.html +1 -1
  699. package/docs/variables/_saltcorn_data.models_index.random.all_views.html +1 -1
  700. package/docs/variables/_saltcorn_data.models_index.random.fill_table_row.html +1 -1
  701. package/docs/variables/_saltcorn_data.models_index.random.initial_view.html +1 -1
  702. package/docs/variables/_saltcorn_data.models_index.random.random_table.html +1 -1
  703. package/docs/variables/_saltcorn_data.models_index.scheduler.runScheduler.html +1 -1
  704. package/docs/variables/_saltcorn_data.models_layout.layout.html +1 -1
  705. package/docs/variables/_saltcorn_data.models_random.random.html +1 -1
  706. package/docs/variables/_saltcorn_data.models_scheduler.scheduler.html +1 -1
  707. package/docs/variables/_saltcorn_data.plugin-helper.add_free_variables_to_joinfields.html +1 -1
  708. package/docs/variables/_saltcorn_data.tests_mocks.mocks.html +1 -1
  709. package/docs/variables/_saltcorn_data.tests_remote_query_helper.renderEditInEditConfig.html +1 -1
  710. package/docs/variables/_saltcorn_data.utils.utils.html +11 -5
  711. package/docs/variables/_saltcorn_data.web-mobile-commons.webMobileCommons.html +1 -1
  712. package/docs/variables/_saltcorn_db-common.internal.dbCommonModulePath.html +1 -1
  713. package/docs/variables/_saltcorn_db-common.multi-tenant.tenantNamespace.html +1 -1
  714. package/docs/variables/_saltcorn_db-common.tenants.tenants.html +1 -1
  715. package/docs/variables/_saltcorn_markup..export_.html +1 -1
  716. package/docs/variables/_saltcorn_markup.builder.builder.html +1 -1
  717. package/docs/variables/_saltcorn_markup.emergency_layout.EmergencyLayoutExports.html +1 -1
  718. package/docs/variables/_saltcorn_markup.form.form.html +1 -1
  719. package/docs/variables/_saltcorn_markup.helpers.HelpersExports.html +1 -1
  720. package/docs/variables/_saltcorn_markup.layout.LayoutExports-1.html +1 -1
  721. package/docs/variables/_saltcorn_markup.layout.LayoutExports.html +1 -1
  722. package/docs/variables/_saltcorn_markup.layout_utils.layoutUtils.html +1 -1
  723. package/docs/variables/_saltcorn_markup.mjml-layout.LayoutExports.html +1 -1
  724. package/docs/variables/_saltcorn_markup.mjml-tags.tagsExports.html +1 -1
  725. package/docs/variables/_saltcorn_markup.table.TableExports.html +1 -1
  726. package/docs/variables/_saltcorn_markup.tags.tagsExports.html +1 -1
  727. package/docs/variables/_saltcorn_types..generators.generateBool.html +1 -1
  728. package/docs/variables/_saltcorn_types..generators.generateString.html +1 -1
  729. package/docs/variables/_saltcorn_types..generators.num_between.html +1 -1
  730. package/docs/variables/_saltcorn_types..generators.oneOf.html +1 -1
  731. package/docs/variables/_saltcorn_types.generators.generators.html +1 -1
  732. package/errors.js +4 -4
  733. package/help/Event channel and payload.tmd +5 -0
  734. package/help/Extra state formula.tmd +1 -1
  735. package/help/Group by formula.tmd +15 -0
  736. package/help/JavaScript action code.tmd +5 -1
  737. package/load_plugins.js +7 -398
  738. package/locales/ar.json +262 -1
  739. package/locales/de.json +264 -3
  740. package/locales/en.json +29 -9
  741. package/locales/es.json +265 -4
  742. package/locales/fr.json +263 -2
  743. package/locales/ur.json +273 -4
  744. package/markup/admin.js +14 -9
  745. package/markup/expression_blurb.js +1 -1
  746. package/package.json +14 -14
  747. package/public/monaco/loader.js +0 -2
  748. package/public/popper.min.js +0 -1
  749. package/public/saltcorn-builder.css +82 -0
  750. package/public/saltcorn-common.js +36 -2
  751. package/public/saltcorn.css +138 -0
  752. package/public/saltcorn.js +1457 -29
  753. package/public/socket.io.min.js +0 -1
  754. package/public/tabulator.min.js +2 -3
  755. package/public/tabulator_bootstrap4.min.css +1 -2
  756. package/public/tabulator_bootstrap5.min.css +1 -2
  757. package/routes/actions.js +224 -22
  758. package/routes/admin.js +71 -12
  759. package/routes/api.js +96 -60
  760. package/routes/delete.js +2 -5
  761. package/routes/edit.js +2 -5
  762. package/routes/entities.js +65 -1245
  763. package/routes/eventlog.js +47 -0
  764. package/routes/fields.js +125 -14
  765. package/routes/files.js +36 -4
  766. package/routes/homepage.js +4 -1
  767. package/routes/list.js +69 -11
  768. package/routes/packs.js +2 -3
  769. package/routes/page.js +18 -1
  770. package/routes/pageedit.js +1 -0
  771. package/routes/plugins.js +56 -21
  772. package/routes/scapi.js +1 -2
  773. package/routes/sync.js +183 -54
  774. package/routes/tables.js +492 -2
  775. package/routes/tenant.js +3 -3
  776. package/routes/utils.js +17 -6
  777. package/routes/viewedit.js +10 -6
  778. package/serve.js +35 -23
  779. package/tests/admin.test.js +5 -5
  780. package/tests/api.test.js +424 -2
  781. package/tests/auth.test.js +230 -1
  782. package/tests/fields.test.js +16 -0
  783. package/tests/files.test.js +43 -7
  784. package/tests/page.test.js +53 -0
  785. package/tests/plugin_install.test.js +132 -13
  786. package/tests/plugins.test.js +1 -2
  787. package/tests/sync.test.js +900 -18
  788. package/tests/view.test.js +32 -0
  789. package/wrapper.js +3 -1
package/serve.js CHANGED
@@ -24,11 +24,6 @@ const path = require("path");
24
24
  const getApp = require("./app");
25
25
  const Trigger = require("@saltcorn/data/models/trigger");
26
26
  const cluster = require("cluster");
27
- const {
28
- loadAllPlugins,
29
- loadAndSaveNewPlugin,
30
- loadPlugin,
31
- } = require("./load_plugins");
32
27
  const { getConfig, setConfig } = require("@saltcorn/data/models/config");
33
28
  const { migrate } = require("@saltcorn/data/migrate");
34
29
  const socketio = require("socket.io");
@@ -255,7 +250,7 @@ const initMaster = async (
255
250
  async () => await migrate(db.connectObj.default_schema, true)
256
251
  );
257
252
  // load all plugins
258
- await loadAllPlugins(true);
253
+ await Plugin.loadAllPlugins(true);
259
254
  // switch on sql logging - but it was initiated before???
260
255
  if (getState().getConfig("log_sql", false)) db.set_sql_logging();
261
256
 
@@ -265,7 +260,7 @@ const initMaster = async (
265
260
  if (db.is_it_multi_tenant()) {
266
261
  const tenants = await getAllTenants();
267
262
  await init_multi_tenant(
268
- () => loadAllPlugins(true),
263
+ () => Plugin.loadAllPlugins(true),
269
264
  disableMigrate,
270
265
  tenants,
271
266
  db.connectObj.multi_node ? getMultiNodeListener : null
@@ -287,7 +282,7 @@ const workerDispatchMsg = ({ tenant, ...msg }) => {
287
282
 
288
283
  if (msg.refresh_plugin_cfg) {
289
284
  Plugin.findOne({ name: msg.refresh_plugin_cfg }).then((plugin) => {
290
- if (plugin) loadPlugin(plugin);
285
+ if (plugin) Plugin.loadPlugin(plugin);
291
286
  });
292
287
  }
293
288
  if (!getState()) {
@@ -307,6 +302,7 @@ const workerDispatchMsg = ({ tenant, ...msg }) => {
307
302
  tenant || "public",
308
303
  msg.real_time_collab_event.type,
309
304
  msg.real_time_collab_event.data,
305
+ msg.real_time_collab_event.viewname,
310
306
  true
311
307
  );
312
308
  }
@@ -325,7 +321,7 @@ const workerDispatchMsg = ({ tenant, ...msg }) => {
325
321
  }
326
322
 
327
323
  if (msg.reload_plugins) {
328
- loadAllPlugins(cluster.isPrimary, true);
324
+ Plugin.loadAllPlugins(cluster.isPrimary, true);
329
325
  }
330
326
  if (msg.refresh) {
331
327
  if (msg.refresh === "ephemeral_config")
@@ -337,7 +333,7 @@ const workerDispatchMsg = ({ tenant, ...msg }) => {
337
333
  add_tenant(msg.createTenant);
338
334
  create_tenant({
339
335
  t: msg.createTenant,
340
- plugin_loader: loadAllPlugins,
336
+ plugin_loader: Plugin.loadAllPlugins,
341
337
  noSignalOrDB: true,
342
338
  tenant_template,
343
339
  });
@@ -346,9 +342,9 @@ const workerDispatchMsg = ({ tenant, ...msg }) => {
346
342
  });
347
343
  }
348
344
  if (msg.installPlugin) {
349
- loadAndSaveNewPlugin(msg.installPlugin, msg.force, true);
345
+ Plugin.loadAndSaveNewPlugin(msg.installPlugin, msg.force, true);
350
346
  }
351
- if (msg.restart_tenant) restart_tenant(loadAllPlugins);
347
+ if (msg.restart_tenant) restart_tenant(Plugin.loadAllPlugins);
352
348
  if (msg.removePlugin) getState().remove_plugin(msg.removePlugin, true);
353
349
  };
354
350
 
@@ -508,7 +504,7 @@ module.exports =
508
504
  4,
509
505
  "SIGHUP received: reloading plugins and state for all tenants"
510
506
  );
511
- await loadAllPlugins(true, true);
507
+ await Plugin.loadAllPlugins(true, true);
512
508
  await getState().refresh_plugins(true);
513
509
  Object.entries(cluster.workers || {}).forEach(([wpid, w]) => {
514
510
  w.send({ reload_plugins: true });
@@ -516,7 +512,7 @@ module.exports =
516
512
  if (db.is_it_multi_tenant()) {
517
513
  for (const tenant of await getAllTenants()) {
518
514
  await db.runWithTenant(tenant, async () => {
519
- await loadAllPlugins(true, true);
515
+ await Plugin.loadAllPlugins(true, true);
520
516
  await getState().refresh_plugins(true);
521
517
  Object.entries(cluster.workers || {}).forEach(([wpid, w]) => {
522
518
  w.send({ tenant, reload_plugins: true });
@@ -850,22 +846,35 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
850
846
  });
851
847
 
852
848
  // Real-time collaboration emitter (tied to views)
853
- getState().setCollabEmitter((tenant, type, data) => {
854
- io.of("/").to(`_${tenant}_collab_room_`).emit(type, data);
849
+ getState().setCollabEmitter((tenant, type, data, viewname) => {
850
+ io.of("/").to(`_${tenant}_collab_room_${viewname}_`).emit(type, data);
855
851
  });
856
852
 
857
853
  // dynamic updates emitter (for run_js_actions)
858
854
  getState().setDynamicUpdateEmitter((tenant, data, userIds) => {
859
- if (userIds) {
855
+ if (userIds === null) {
856
+ // explicit public-only; data may carry page_load_tag for client-side filtering
857
+ io.of("/")
858
+ .to(`_${tenant}_public_dynamic_update_room`)
859
+ .emit("dynamic_update", data);
860
+ } else if (Array.isArray(userIds)) {
860
861
  for (const userId of userIds) {
861
862
  io.of("/")
862
863
  .to(`_${tenant}:${userId}_dynamic_update_room`)
863
864
  .emit("dynamic_update", data);
864
865
  }
865
- } else {
866
+ } else if (userIds === undefined) {
867
+ // broadcast to all authenticated users in this tenant
866
868
  io.of("/")
867
869
  .to(`_${tenant}_dynamic_update_room`)
868
870
  .emit("dynamic_update", data);
871
+ } else {
872
+ getState().log(
873
+ 1,
874
+ `setDynamicUpdateEmitter: unexpected userIds value: ${JSON.stringify(
875
+ userIds
876
+ )}`
877
+ );
869
878
  }
870
879
  });
871
880
 
@@ -932,9 +941,9 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
932
941
  const role_id = user ? user.role_id : 100;
933
942
  if (view.min_role < role_id)
934
943
  throw new Error("Not authorized to join collaboration room");
935
- const roomName = `_${tenant}_collab_room_`;
944
+ const roomName = `_${tenant}_collab_room_${viewname}_`;
936
945
  if (!socket.rooms.has(roomName)) {
937
- socket.join(`_${tenant}_collab_room_`);
946
+ socket.join(roomName);
938
947
  if (typeof callback === "function") callback({ status: "ok" });
939
948
  const socketIds = await getState().getConfig(
940
949
  "joined_real_time_socket_ids",
@@ -966,9 +975,12 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
966
975
  const enabled = getState().getConfig("enable_dynamic_updates", true);
967
976
  if (!enabled) throw new Error("Dynamic updates are not enabled");
968
977
  const user = socket.request.user;
969
- if (!user) throw new Error("Not authorized");
970
- socket.join(`_${tenant}_dynamic_update_room`);
971
- socket.join(`_${tenant}:${user.id}_dynamic_update_room`);
978
+ if (user) {
979
+ socket.join(`_${tenant}:${user.id}_dynamic_update_room`);
980
+ socket.join(`_${tenant}_dynamic_update_room`);
981
+ } else {
982
+ socket.join(`_${tenant}_public_dynamic_update_room`);
983
+ }
972
984
  const socketIds = await getState().getConfig(
973
985
  "joined_dynamic_update_socket_ids",
974
986
  []
@@ -25,7 +25,7 @@ const {
25
25
  auto_backup_now,
26
26
  } = require("@saltcorn/admin-models/models/backup");
27
27
 
28
- jest.setTimeout(30000);
28
+ jest.setTimeout(30000000);
29
29
 
30
30
  beforeAll(async () => {
31
31
  await resetToFixtures();
@@ -387,7 +387,7 @@ describe("actions", () => {
387
387
  .send("table_id=2")
388
388
  .send("name=mynewaction")
389
389
  .send("when_trigger=Insert")
390
- .expect(toRedirect("/actions/configure/8"));
390
+ .expect(toRedirect("/actions/configure/9"));
391
391
  });
392
392
  it("show edit", async () => {
393
393
  const app = await getApp({ disableCsrf: true });
@@ -451,9 +451,9 @@ describe("actions", () => {
451
451
  .send("action=run_js_code")
452
452
  .send("when_trigger=API+call")
453
453
  .send("min_role=1")
454
- .expect(toRedirect("/actions/configure/9"));
454
+ .expect(toRedirect("/actions/configure/10"));
455
455
  await request(app)
456
- .post("/actions/configure/9")
456
+ .post("/actions/configure/10")
457
457
  .set("Cookie", loginCookie)
458
458
  .send("code=return 27")
459
459
  .expect(toRedirect("/actions/"));
@@ -461,7 +461,7 @@ describe("actions", () => {
461
461
  .post("/api/action/myact")
462
462
  .set("Cookie", loginCookie)
463
463
  .expect(
464
- respondJsonWith(200, ({ success, data }) => success && data === 27)
464
+ respondJsonWith(200, ({ success, data }) => success === true && data === 27)
465
465
  );
466
466
  });
467
467
  it("deletes trigger", async () => {
package/tests/api.test.js CHANGED
@@ -760,7 +760,7 @@ describe("API emit", () => {
760
760
  const app = await getApp({ disableCsrf: true });
761
761
  const token = await getAdminJwt();
762
762
  await request(app)
763
- .post("/api/emit-event/event1")
763
+ .post("/api/emit-event/ReceiveMobileShareData")
764
764
  .set("Authorization", `jwt ${token}`)
765
765
  .send({ payload: { latitude: 20, longitude: 30 } })
766
766
  .expect(succeedJsonWith((success) => success === true));
@@ -770,12 +770,137 @@ describe("API emit", () => {
770
770
  it("denies an event without JWT", async () => {
771
771
  const app = await getApp({ disableCsrf: true });
772
772
  await request(app)
773
- .post("/api/emit-event/event1")
773
+ .post("/api/emit-event/ReceiveMobileShareData")
774
774
  .send({ payload: { latitude: 20, longitude: 30 } })
775
775
  .expect(notAuthorized);
776
776
  });
777
777
  });
778
778
 
779
+ describe("API emit-event access control", () => {
780
+ const getPublicJwt = async () => {
781
+ const app = await getApp({ disableCsrf: true });
782
+ const res = await request(app)
783
+ .post("/auth/login-with/jwt")
784
+ .set("X-Requested-With", "XMLHttpRequest")
785
+ .set("X-Saltcorn-Client", "mobile-app")
786
+ .send({});
787
+ return res.body;
788
+ };
789
+
790
+ let adminJwt;
791
+ beforeAll(async () => {
792
+ adminJwt = await getAdminJwt();
793
+ });
794
+
795
+ afterEach(async () => {
796
+ await getState().setConfig("mobile_emit_allowed_events", []);
797
+ await getState().setConfig("mobile_emit_public_events", []);
798
+ });
799
+
800
+ // --- authenticated user ---
801
+
802
+ it("allows authenticated user to emit ReceiveMobileShareData by default", async () => {
803
+ const app = await getApp({ disableCsrf: true });
804
+ await request(app)
805
+ .post("/api/emit-event/ReceiveMobileShareData")
806
+ .set("Authorization", `jwt ${adminJwt}`)
807
+ .send({ payload: {} })
808
+ .expect(succeedJsonWith((success) => success === true));
809
+ });
810
+
811
+ it("blocks authenticated user from emitting other events by default", async () => {
812
+ const app = await getApp({ disableCsrf: true });
813
+ for (const eventName of [
814
+ "AppChange",
815
+ "Login",
816
+ "Error",
817
+ "Startup",
818
+ "UserVerified",
819
+ ]) {
820
+ await request(app)
821
+ .post(`/api/emit-event/${eventName}`)
822
+ .set("Authorization", `jwt ${adminJwt}`)
823
+ .send({ payload: {} })
824
+ .expect(
825
+ respondJsonWith(
826
+ 403,
827
+ (resp) => resp.error === "Event type not allowed"
828
+ )
829
+ );
830
+ }
831
+ });
832
+
833
+ it("allows authenticated user to emit event listed in mobile_emit_allowed_events config", async () => {
834
+ await getState().setConfig("mobile_emit_allowed_events", ["AppChange"]);
835
+ const app = await getApp({ disableCsrf: true });
836
+ await request(app)
837
+ .post("/api/emit-event/AppChange")
838
+ .set("Authorization", `jwt ${adminJwt}`)
839
+ .send({ payload: {} })
840
+ .expect(succeedJsonWith((success) => success === true));
841
+ });
842
+
843
+ it("blocks authenticated user from emitting event not listed in mobile_emit_allowed_events config", async () => {
844
+ await getState().setConfig("mobile_emit_allowed_events", ["AppChange"]);
845
+ const app = await getApp({ disableCsrf: true });
846
+ await request(app)
847
+ .post("/api/emit-event/Login")
848
+ .set("Authorization", `jwt ${adminJwt}`)
849
+ .send({ payload: {} })
850
+ .expect(
851
+ respondJsonWith(403, (resp) => resp.error === "Event type not allowed")
852
+ );
853
+ });
854
+
855
+ // --- public user ---
856
+
857
+ it("blocks public JWT user from emitting any event by default", async () => {
858
+ const publicJwt = await getPublicJwt();
859
+ const app = await getApp({ disableCsrf: true });
860
+ await request(app)
861
+ .post("/api/emit-event/ReceiveMobileShareData")
862
+ .set("Authorization", `jwt ${publicJwt}`)
863
+ .send({ payload: {} })
864
+ .expect(notAuthorized);
865
+ });
866
+
867
+ it("allows public JWT user to emit event listed in mobile_emit_public_events config", async () => {
868
+ await getState().setConfig("mobile_emit_public_events", [
869
+ "CustomerEnquiry",
870
+ ]);
871
+ const publicJwt = await getPublicJwt();
872
+ const app = await getApp({ disableCsrf: true });
873
+ await request(app)
874
+ .post("/api/emit-event/CustomerEnquiry")
875
+ .set("Authorization", `jwt ${publicJwt}`)
876
+ .send({ payload: {} })
877
+ .expect(succeedJsonWith((success) => success === true));
878
+ });
879
+
880
+ it("blocks public JWT user from emitting event not listed in mobile_emit_public_events config", async () => {
881
+ await getState().setConfig("mobile_emit_public_events", [
882
+ "CustomerEnquiry",
883
+ ]);
884
+ const publicJwt = await getPublicJwt();
885
+ const app = await getApp({ disableCsrf: true });
886
+ await request(app)
887
+ .post("/api/emit-event/OtherEvent")
888
+ .set("Authorization", `jwt ${publicJwt}`)
889
+ .send({ payload: {} })
890
+ .expect(notAuthorized);
891
+ });
892
+
893
+ // --- no token ---
894
+
895
+ it("blocks request with no JWT at all", async () => {
896
+ const app = await getApp({ disableCsrf: true });
897
+ await request(app)
898
+ .post("/api/emit-event/ReceiveMobileShareData")
899
+ .send({ payload: {} })
900
+ .expect(notAuthorized);
901
+ });
902
+ });
903
+
779
904
  describe("test share handler", () => {
780
905
  beforeAll(async () => {
781
906
  const sharedData = await Table.create("shared_data");
@@ -885,3 +1010,300 @@ describe("API upload-files", () => {
885
1010
  .expect(respondJsonWith(400, (resp) => resp.error === "No file found"));
886
1011
  });
887
1012
  });
1013
+
1014
+ describe("API cross-table sub-select access control", () => {
1015
+ it("should not allow probing restricted tables via sub-select query syntax", async () => {
1016
+ const app = await getApp({ disableCsrf: true });
1017
+ // The patients table has min_role_read=40 (staff).
1018
+ // A public user should not be able to learn anything about patients data.
1019
+ // The books table is public (min_role_read=100).
1020
+ // The sub-select syntax (e.g. ?id.patients->name=Kirk) constructs:
1021
+ // WHERE id IN (SELECT id FROM patients WHERE name ILIKE '%Kirk%')
1022
+ // This leaks whether a patient named "Kirk" exists by observing
1023
+ // whether any books are returned.
1024
+ const patients = Table.findOne({ name: "patients" });
1025
+ expect(patients.min_role_read).toBe(40);
1026
+
1027
+ // Query WITH a name that exists in patients ("Kirk Douglas", id=1)
1028
+ const resp1 = await request(app)
1029
+ .get("/api/books/?id.patients->name=Kirk")
1030
+ .expect(200);
1031
+
1032
+ // Query with a name that does NOT exist in patients
1033
+ const resp2 = await request(app)
1034
+ .get("/api/books/?id.patients->name=ZZZNONEXISTENT")
1035
+ .expect(200);
1036
+
1037
+ // If the sub-select is allowed, resp1 returns books (because patient
1038
+ // "Kirk Douglas" has id=1 which matches book id=1) while resp2
1039
+ // returns nothing. The difference reveals that "Kirk" exists in the
1040
+ // restricted patients table.
1041
+ //
1042
+ // The secure behavior is that both queries return the same results
1043
+ // (the sub-select against a restricted table is ignored or blocked),
1044
+ // OR the query with the sub-select is rejected entirely.
1045
+ const rows1 = resp1.body.success || [];
1046
+ const rows2 = resp2.body.success || [];
1047
+ expect(rows1.length).toBe(rows2.length);
1048
+ });
1049
+
1050
+ it("should not allow probing restricted tables via or parameter with inSelect", async () => {
1051
+ const app = await getApp({ disableCsrf: true });
1052
+ // The patients table has min_role_read=40 (staff).
1053
+ // The books table is public (min_role_read=100).
1054
+ //
1055
+ // The 'or' query parameter is passed directly through stateFieldsToWhere
1056
+ // into the db where-clause without access control checks. An attacker
1057
+ // can embed an inSelect subquery in 'or' to probe restricted tables:
1058
+ // ?or[0][id][inSelect][table]=patients&or[0][id][inSelect][field]=favbook
1059
+ // &or[0][id][inSelect][where][name]=Kirk Douglas
1060
+ // This generates: WHERE (id IN (SELECT favbook FROM patients WHERE name='Kirk Douglas'))
1061
+ // By observing which books are returned, the attacker can determine
1062
+ // whether a patient with a given name exists — leaking data from the
1063
+ // restricted patients table.
1064
+ const patients = Table.findOne({ name: "patients" });
1065
+ expect(patients.min_role_read).toBe(40);
1066
+
1067
+ // Kirk Douglas exists in patients with favbook=1 (Herman Melville)
1068
+ const resp1 = await request(app)
1069
+ .get("/api/books/")
1070
+ .query({
1071
+ "or[0][id][inSelect][table]": "patients",
1072
+ "or[0][id][inSelect][field]": "favbook",
1073
+ "or[0][id][inSelect][where][name]": "Kirk Douglas",
1074
+ })
1075
+ .expect(200);
1076
+
1077
+ // Non-existent patient
1078
+ const resp2 = await request(app)
1079
+ .get("/api/books/")
1080
+ .query({
1081
+ "or[0][id][inSelect][table]": "patients",
1082
+ "or[0][id][inSelect][field]": "favbook",
1083
+ "or[0][id][inSelect][where][name]": "ZZZNONEXISTENT",
1084
+ })
1085
+ .expect(200);
1086
+
1087
+ // If the or+inSelect bypass works, resp1 returns only book id=1
1088
+ // (Kirk Douglas's favbook) while resp2 returns nothing.
1089
+ // Secure behavior: both return the same results (all books or error).
1090
+ const rows1 = resp1.body.success || [];
1091
+ const rows2 = resp2.body.success || [];
1092
+ expect(rows1.length).toBe(rows2.length);
1093
+ });
1094
+
1095
+ it("should not allow probing restricted tables via field object with inSelect", async () => {
1096
+ const app = await getApp({ disableCsrf: true });
1097
+ // When a field value is an object, stateFieldsToWhere passes it through
1098
+ // directly. An attacker can embed inSelect in a known field name:
1099
+ // ?id[inSelect][table]=patients&id[inSelect][field]=favbook&...
1100
+ const patients = Table.findOne({ name: "patients" });
1101
+ expect(patients.min_role_read).toBe(40);
1102
+
1103
+ const resp1 = await request(app)
1104
+ .get("/api/books/")
1105
+ .query({
1106
+ "id[inSelect][table]": "patients",
1107
+ "id[inSelect][field]": "favbook",
1108
+ "id[inSelect][where][name]": "Kirk Douglas",
1109
+ })
1110
+ .expect(200);
1111
+
1112
+ const resp2 = await request(app)
1113
+ .get("/api/books/")
1114
+ .query({
1115
+ "id[inSelect][table]": "patients",
1116
+ "id[inSelect][field]": "favbook",
1117
+ "id[inSelect][where][name]": "ZZZNONEXISTENT",
1118
+ })
1119
+ .expect(200);
1120
+
1121
+ const rows1 = resp1.body.success || [];
1122
+ const rows2 = resp2.body.success || [];
1123
+ expect(rows1.length).toBe(rows2.length);
1124
+ });
1125
+
1126
+ it("should not allow probing restricted tables via _not_ prefix with inSelect", async () => {
1127
+ const app = await getApp({ disableCsrf: true });
1128
+ // The _not_ prefix passes user values into qstate.not[field].
1129
+ // An attacker can embed inSelect to leak data:
1130
+ // ?_not_id[inSelect][table]=patients&_not_id[inSelect][field]=favbook&...
1131
+ const patients = Table.findOne({ name: "patients" });
1132
+ expect(patients.min_role_read).toBe(40);
1133
+
1134
+ const resp1 = await request(app)
1135
+ .get("/api/books/")
1136
+ .query({
1137
+ "_not_id[inSelect][table]": "patients",
1138
+ "_not_id[inSelect][field]": "favbook",
1139
+ "_not_id[inSelect][where][name]": "Kirk Douglas",
1140
+ })
1141
+ .expect(200);
1142
+
1143
+ const resp2 = await request(app)
1144
+ .get("/api/books/")
1145
+ .query({
1146
+ "_not_id[inSelect][table]": "patients",
1147
+ "_not_id[inSelect][field]": "favbook",
1148
+ "_not_id[inSelect][where][name]": "ZZZNONEXISTENT",
1149
+ })
1150
+ .expect(200);
1151
+
1152
+ const rows1 = resp1.body.success || [];
1153
+ const rows2 = resp2.body.success || [];
1154
+ expect(rows1.length).toBe(rows2.length);
1155
+ });
1156
+
1157
+ it("should not allow probing restricted tables via _relation_path_ parameter", async () => {
1158
+ const app = await getApp({ disableCsrf: true });
1159
+ // The _relation_path_ query parameter accepts JSON that specifies a
1160
+ // relation path through arbitrary tables. handleRelationPath() constructs
1161
+ // an inSelectWithLevels subquery with NO authorization checks.
1162
+ //
1163
+ // Attack: query the public books table with a _relation_path_ that
1164
+ // traverses the restricted patients table (min_role_read=40):
1165
+ // ?_relation_path_={"relation":".books.patients$name","srcId":"Kirk Douglas"}
1166
+ // This generates:
1167
+ // WHERE id IN (SELECT id FROM patients WHERE name = 'Kirk Douglas')
1168
+ // A public user can determine whether a patient with a given name exists
1169
+ // by observing which books are returned.
1170
+ const patients = Table.findOne({ name: "patients" });
1171
+ expect(patients.min_role_read).toBe(40);
1172
+
1173
+ // srcId matching an existing patient name
1174
+ const resp1 = await request(app)
1175
+ .get("/api/books/")
1176
+ .query({
1177
+ _relation_path_: JSON.stringify({
1178
+ relation: ".books.patients$name",
1179
+ srcId: "Kirk Douglas",
1180
+ }),
1181
+ })
1182
+ .expect(200);
1183
+
1184
+ // srcId with a non-existent patient name
1185
+ const resp2 = await request(app)
1186
+ .get("/api/books/")
1187
+ .query({
1188
+ _relation_path_: JSON.stringify({
1189
+ relation: ".books.patients$name",
1190
+ srcId: "ZZZNONEXISTENT",
1191
+ }),
1192
+ })
1193
+ .expect(200);
1194
+
1195
+ // If the relation_path is allowed without authorization, resp1 returns
1196
+ // book id=1 (because patient "Kirk Douglas" has id=1) while resp2
1197
+ // returns nothing. The difference reveals that "Kirk Douglas" exists
1198
+ // in the restricted patients table.
1199
+ //
1200
+ // Secure behavior: both queries return the same results (the subquery
1201
+ // against the restricted table is blocked or ignored), OR the query
1202
+ // is rejected.
1203
+ const rows1 = resp1.body.success || [];
1204
+ const rows2 = resp2.body.success || [];
1205
+ expect(rows1.length).toBe(rows2.length);
1206
+ });
1207
+
1208
+ it("should not allow probing restricted tables via dot-prefix relation path", async () => {
1209
+ const app = await getApp({ disableCsrf: true });
1210
+ // The dot-prefix syntax (e.g. ?.books.patients$name=value) is another
1211
+ // way to invoke handleRelationPath, which has no authorization checks.
1212
+ // This constructs the same inSelectWithLevels subquery.
1213
+ const patients = Table.findOne({ name: "patients" });
1214
+ expect(patients.min_role_read).toBe(40);
1215
+
1216
+ const resp1 = await request(app)
1217
+ .get("/api/books/")
1218
+ .query({ ".books.patients$name": "Kirk Douglas" })
1219
+ .expect(200);
1220
+
1221
+ const resp2 = await request(app)
1222
+ .get("/api/books/")
1223
+ .query({ ".books.patients$name": "ZZZNONEXISTENT" })
1224
+ .expect(200);
1225
+
1226
+ const rows1 = resp1.body.success || [];
1227
+ const rows2 = resp2.body.success || [];
1228
+ expect(rows1.length).toBe(rows2.length);
1229
+ });
1230
+ });
1231
+
1232
+ describe("API CSRF protection", () => {
1233
+ let adminToken, adminJwt;
1234
+
1235
+ beforeAll(async () => {
1236
+ const admin = await User.findOne({ email: "admin@foo.com" });
1237
+ adminToken = await admin.getNewAPIToken();
1238
+ adminJwt = await getAdminJwt();
1239
+ await Trigger.create({
1240
+ action: "run_js_code",
1241
+ when_trigger: "API call",
1242
+ name: "apicallpublic1",
1243
+ min_role: 100,
1244
+ configuration: {
1245
+ code: `return {foo: "bar"}`,
1246
+ },
1247
+ });
1248
+ });
1249
+
1250
+ it("should reject POST with session cookie but no CSRF token", async () => {
1251
+ const app = await getApp({ disableCsrf: false });
1252
+ const loginCookie = await getAdminLoginCookie();
1253
+ await request(app)
1254
+ .post("/api/books/")
1255
+ .set("Cookie", loginCookie)
1256
+ .send({ author: "CSRF Test", pages: 1 })
1257
+ .set("Content-Type", "application/json")
1258
+ .expect(302);
1259
+ });
1260
+
1261
+ it("should allow POST with bearer token and no CSRF token", async () => {
1262
+ const app = await getApp({ disableCsrf: false });
1263
+ await request(app)
1264
+ .post("/api/books/")
1265
+ .set("Authorization", "Bearer " + adminToken)
1266
+ .send({ author: "Bearer No CSRF", pages: 2 })
1267
+ .set("Content-Type", "application/json")
1268
+ .set("Accept", "application/json")
1269
+ .expect(succeedJsonWith((resp) => resp && typeof resp === "number"));
1270
+ });
1271
+
1272
+ it("should allow POST to public api with no bearer token and no CSRF token", async () => {
1273
+ const app = await getApp({ disableCsrf: false });
1274
+ await request(app)
1275
+ .post("/api/action/apicallpublic1")
1276
+ .send({})
1277
+ .set("Content-Type", "application/json")
1278
+ .set("Accept", "application/json")
1279
+ .expect(200)
1280
+ .expect(
1281
+ succeedJsonWithWholeBody(
1282
+ (resp) => resp?.data?.foo === "bar" && resp.success === true
1283
+ )
1284
+ );
1285
+ });
1286
+
1287
+ it("should allow POST with valid JWT and no CSRF token", async () => {
1288
+ const app = await getApp({ disableCsrf: false });
1289
+ await request(app)
1290
+ .post("/api/books/")
1291
+ .set("Authorization", `jwt ${adminJwt}`)
1292
+ .send({ author: "JWT No CSRF", pages: 3 })
1293
+ .set("Content-Type", "application/json")
1294
+ .set("Accept", "application/json")
1295
+ .expect(succeedJsonWith((resp) => resp && typeof resp === "number"));
1296
+ });
1297
+
1298
+ it("should not bypass CSRF by appending a fake ?jwt= query parameter", async () => {
1299
+ const app = await getApp({ disableCsrf: false });
1300
+ const loginCookie = await getAdminLoginCookie();
1301
+
1302
+ await request(app)
1303
+ .post("/api/books/?jwt=fakejwt")
1304
+ .send({ author: "CSRF Bypass Attempt", pages: 4 })
1305
+ .set("Cookie", loginCookie)
1306
+ .set("Content-Type", "application/json")
1307
+ .expect(302);
1308
+ });
1309
+ });