@saltcorn/server 1.3.1-beta.1 → 1.3.1-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.
- package/CHANGELOG.md +29 -0
- package/auth/admin.js +9 -1
- package/auth/routes.js +50 -5
- package/docs/assets/search.js +1 -1
- package/docs/classes/_saltcorn_common_code.Relation.html +10 -10
- package/docs/classes/_saltcorn_common_code.RelationsFinder.html +5 -5
- package/docs/classes/_saltcorn_data.models.Crash.html +17 -17
- package/docs/classes/_saltcorn_data.models.EventLog-1.html +19 -19
- package/docs/classes/_saltcorn_data.models.Field.html +74 -74
- package/docs/classes/_saltcorn_data.models.FieldRepeat.html +16 -16
- package/docs/classes/_saltcorn_data.models.File-1.html +48 -48
- package/docs/classes/_saltcorn_data.models.Form-1.html +39 -39
- package/docs/classes/_saltcorn_data.models.Library.html +13 -13
- package/docs/classes/_saltcorn_data.models.Page.html +24 -24
- package/docs/classes/_saltcorn_data.models.PageGroup-1.html +25 -25
- package/docs/classes/_saltcorn_data.models.Plugin.html +25 -25
- package/docs/classes/_saltcorn_data.models.Role.html +9 -9
- package/docs/classes/_saltcorn_data.models.Table-1.html +92 -92
- package/docs/classes/_saltcorn_data.models.TableConstraint.html +14 -14
- package/docs/classes/_saltcorn_data.models.Trigger.html +71 -39
- package/docs/classes/_saltcorn_data.models.User.html +51 -49
- package/docs/classes/_saltcorn_data.models.View-1.html +54 -54
- package/docs/classes/_saltcorn_data.models.Workflow.html +17 -17
- package/docs/classes/_saltcorn_data.models.WorkflowRun.html +35 -35
- package/docs/classes/_saltcorn_data.models.WorkflowStep.html +25 -25
- package/docs/classes/_saltcorn_data.models.WorkflowTrace.html +18 -18
- package/docs/classes/_saltcorn_mobile_builder.MobileBuilder.html +37 -37
- package/docs/enums/_saltcorn_common_code.RelationType.html +7 -7
- package/docs/enums/_saltcorn_common_code.ViewDisplayType.html +4 -4
- package/docs/functions/_saltcorn_admin_models.backup.create_backup.html +1 -1
- package/docs/functions/_saltcorn_admin_models.backup.create_csv_from_rows.html +1 -1
- package/docs/functions/_saltcorn_admin_models.backup.restore.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.add_to_menu.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.can_install_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.fetch_available_packs.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.fetch_pack_by_name.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.install_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.library_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.model_instance_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.model_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.page_group_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.page_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.plugin_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.role_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.table_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.trigger_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.uninstall_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.pack.view_pack.html +1 -1
- package/docs/functions/_saltcorn_admin_models.tenant.copy_tenant_template.html +1 -1
- package/docs/functions/_saltcorn_admin_models.tenant.create_tenant.html +1 -1
- package/docs/functions/_saltcorn_admin_models.tenant.deleteTenant.html +1 -1
- package/docs/functions/_saltcorn_admin_models.tenant.domain_sanitize.html +1 -1
- package/docs/functions/_saltcorn_admin_models.tenant.eachTenant.html +1 -1
- package/docs/functions/_saltcorn_admin_models.tenant.getAllTenantRows.html +1 -1
- package/docs/functions/_saltcorn_admin_models.tenant.getAllTenants.html +1 -1
- package/docs/functions/_saltcorn_admin_models.tenant.insertTenant.html +1 -1
- package/docs/functions/_saltcorn_admin_models.tenant.switchToTenant.html +1 -1
- package/docs/functions/_saltcorn_common_code.buildTableCaches.html +1 -1
- package/docs/functions/_saltcorn_common_code.parseLegacyRelation.html +1 -1
- package/docs/functions/_saltcorn_common_code.parseRelationPath.html +1 -1
- package/docs/functions/_saltcorn_data.models.config.check_email_mask.html +1 -1
- package/docs/functions/_saltcorn_data.models.config.deleteConfig.html +1 -1
- package/docs/functions/_saltcorn_data.models.config.getAllConfig.html +1 -1
- package/docs/functions/_saltcorn_data.models.config.getConfig.html +1 -1
- package/docs/functions/_saltcorn_data.models.config.get_base_url.html +1 -1
- package/docs/functions/_saltcorn_data.models.config.get_latest_npm_version.html +1 -1
- package/docs/functions/_saltcorn_data.models.config.remove_from_menu.html +1 -1
- package/docs/functions/_saltcorn_data.models.config.save_menu_items.html +1 -1
- package/docs/functions/_saltcorn_data.models.config.setConfig.html +1 -1
- package/docs/functions/_saltcorn_data.models.discovery.discover_tables.html +1 -1
- package/docs/functions/_saltcorn_data.models.discovery.discoverable_tables.html +1 -1
- package/docs/functions/_saltcorn_data.models.discovery.findType.html +1 -1
- package/docs/functions/_saltcorn_data.models.discovery.get_existing_views.html +1 -1
- package/docs/functions/_saltcorn_data.models.discovery.implement_discovery.html +1 -1
- package/docs/functions/_saltcorn_data.models.email.getMailTransport.html +1 -1
- package/docs/functions/_saltcorn_data.models.email.send_verification_email.html +1 -1
- package/docs/functions/_saltcorn_data.models.email.viewToEmailHtml.html +1 -1
- package/docs/functions/_saltcorn_data.models.expression.apply_calculated_fields.html +1 -1
- package/docs/functions/_saltcorn_data.models.expression.apply_calculated_fields_stored.html +1 -1
- package/docs/functions/_saltcorn_data.models.expression.eval_expression.html +1 -1
- package/docs/functions/_saltcorn_data.models.expression.expressionValidator.html +1 -1
- package/docs/functions/_saltcorn_data.models.expression.get_async_expression_function.html +1 -1
- package/docs/functions/_saltcorn_data.models.expression.get_expression_function.html +1 -1
- package/docs/functions/_saltcorn_data.models.expression.jsexprToWhere.html +1 -1
- package/docs/functions/_saltcorn_data.models.expression.recalculate_for_stored.html +1 -1
- package/docs/functions/_saltcorn_data.models.expression.transform_for_async.html +1 -1
- package/docs/functions/_saltcorn_data.models.layout.eachView.html +1 -1
- package/docs/functions/_saltcorn_data.models.layout.getStringsForI18n.html +1 -1
- package/docs/functions/_saltcorn_data.models.layout.getViews.html +1 -1
- package/docs/functions/_saltcorn_data.models.layout.translateLayout.html +1 -1
- package/docs/functions/_saltcorn_data.models.layout.traverse.html +1 -1
- package/docs/functions/_saltcorn_data.models.layout.traverseSync.html +1 -1
- package/docs/functions/_saltcorn_data.models.random.all_views.html +1 -1
- package/docs/functions/_saltcorn_data.models.random.fill_table_row.html +1 -1
- package/docs/functions/_saltcorn_data.models.random.initial_view.html +1 -1
- package/docs/functions/_saltcorn_data.models.random.random_table.html +1 -1
- package/docs/functions/_saltcorn_db_common.buildInsertBulkSql.html +2 -1
- package/docs/functions/_saltcorn_db_common.buildInsertSql.html +2 -1
- package/docs/functions/_saltcorn_db_common.commitAndBeginNewTransaction.html +103 -0
- package/docs/functions/_saltcorn_db_common.doCount.html +2 -1
- package/docs/functions/_saltcorn_db_common.doDeleteWhere.html +2 -1
- package/docs/functions/_saltcorn_db_common.doListScTables.html +2 -1
- package/docs/functions/_saltcorn_db_common.doListTables.html +2 -1
- package/docs/functions/_saltcorn_db_common.doListUserDefinedTables.html +2 -1
- package/docs/functions/_saltcorn_db_common.do_add_index.html +2 -1
- package/docs/functions/_saltcorn_db_common.do_drop_index.html +2 -1
- package/docs/functions/_saltcorn_db_common.ftsFieldsSqlExpr.html +2 -1
- package/docs/functions/_saltcorn_db_common.mkSelectOptions.html +2 -1
- package/docs/functions/_saltcorn_db_common.mkVal.html +2 -1
- package/docs/functions/_saltcorn_db_common.mkWhere.html +2 -1
- package/docs/functions/_saltcorn_db_common.multi_tenant.enable_multi_tenant.html +2 -1
- package/docs/functions/_saltcorn_db_common.multi_tenant.getRequestContext.html +2 -1
- package/docs/functions/_saltcorn_db_common.multi_tenant.getTenantSchema.html +2 -1
- package/docs/functions/_saltcorn_db_common.multi_tenant.init.html +2 -1
- package/docs/functions/_saltcorn_db_common.multi_tenant.is_it_multi_tenant.html +2 -1
- package/docs/functions/_saltcorn_db_common.multi_tenant.runWithTenant.html +2 -1
- package/docs/functions/_saltcorn_db_common.orderByIsObject.html +2 -1
- package/docs/functions/_saltcorn_db_common.orderByIsOperator.html +2 -1
- package/docs/functions/_saltcorn_db_common.prefixFieldsInWhere.html +2 -1
- package/docs/functions/_saltcorn_db_common.reprAsJson.html +2 -1
- package/docs/functions/_saltcorn_db_common.slugify.html +2 -1
- package/docs/functions/_saltcorn_db_common.sqlBinOp.html +2 -1
- package/docs/functions/_saltcorn_db_common.sqlFun.html +2 -1
- package/docs/functions/_saltcorn_db_common.sqlsanitize.html +2 -1
- package/docs/functions/_saltcorn_db_common.sqlsanitizeAllowDots.html +2 -1
- package/docs/functions/_saltcorn_db_common.subSelectWhere.html +2 -1
- package/docs/functions/_saltcorn_db_common.tryCatchInTransaction.html +2 -1
- package/docs/functions/_saltcorn_db_common.withTransaction.html +2 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.androidFeatures.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.androidPermissions.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.buildTablesFile.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyPrepopulatedDb.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyServerFiles.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyShareExtFiles.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copySiteLogo.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyTranslationFiles.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.createSqliteDb.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.decodeProvisioningProfile.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.extractDomain.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.generateAndroidVersionCode.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyAndroidManifest.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyConfigXml.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyGradleConfig.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyInfoPlist.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyXcodeProjectFile.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepAppIcon.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareAppIcon.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareBuildDir.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareExportOptionsPlist.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareSplashIcon.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareSplashPage.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeCapacitorConfig.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeCfgFile.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeDataExtractionRules.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeNetworkSecurityConfig.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writePodfile.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writePrivacyInfo.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.bundleMobileAppCode.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.bundlePackagesAndPlugins.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.copyMobileAppDirs.html +1 -1
- package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.copyPublicDirs.html +1 -1
- package/docs/functions/_saltcorn_sqlite.add_index.html +1 -1
- package/docs/functions/_saltcorn_sqlite.add_unique_constraint.html +1 -1
- package/docs/functions/_saltcorn_sqlite.begin.html +1 -1
- package/docs/functions/_saltcorn_sqlite.changeConnection.html +1 -1
- package/docs/functions/_saltcorn_sqlite.close.html +1 -1
- package/docs/functions/_saltcorn_sqlite.commit.html +1 -1
- package/docs/functions/_saltcorn_sqlite.count.html +1 -1
- package/docs/functions/_saltcorn_sqlite.deleteWhere.html +1 -1
- package/docs/functions/_saltcorn_sqlite.dropTable.html +1 -1
- package/docs/functions/_saltcorn_sqlite.dropTables.html +1 -1
- package/docs/functions/_saltcorn_sqlite.drop_index.html +1 -1
- package/docs/functions/_saltcorn_sqlite.drop_reset_schema.html +1 -1
- package/docs/functions/_saltcorn_sqlite.drop_unique_constraint.html +1 -1
- package/docs/functions/_saltcorn_sqlite.getVersion.html +1 -1
- package/docs/functions/_saltcorn_sqlite.get_db_filepath.html +1 -1
- package/docs/functions/_saltcorn_sqlite.get_sql_logging.html +1 -1
- package/docs/functions/_saltcorn_sqlite.init.html +1 -1
- package/docs/functions/_saltcorn_sqlite.insert.html +1 -1
- package/docs/functions/_saltcorn_sqlite.listScTables.html +1 -1
- package/docs/functions/_saltcorn_sqlite.listTables.html +1 -1
- package/docs/functions/_saltcorn_sqlite.listUserDefinedTables.html +1 -1
- package/docs/functions/_saltcorn_sqlite.query.html +1 -1
- package/docs/functions/_saltcorn_sqlite.rollback.html +1 -1
- package/docs/functions/_saltcorn_sqlite.select.html +1 -1
- package/docs/functions/_saltcorn_sqlite.selectMaybeOne.html +1 -1
- package/docs/functions/_saltcorn_sqlite.selectOne.html +1 -1
- package/docs/functions/_saltcorn_sqlite.set_sql_logging.html +1 -1
- package/docs/functions/_saltcorn_sqlite.sql_log.html +1 -1
- package/docs/functions/_saltcorn_sqlite.update.html +1 -1
- package/docs/functions/_saltcorn_sqlite.updateWhere.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.add_index.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.add_unique_constraint.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.count.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.deleteWhere.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.drop_index.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.drop_reset_schema.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.drop_unique_constraint.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.init.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.insert.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.insertRows.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.listScTables.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.listTables.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.listUserDefinedTables.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.query.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.select.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.selectMaybeOne.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.selectOne.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.setConnectionObject.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.tableExists.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.time.html +1 -1
- package/docs/functions/_saltcorn_sqlite_mobile.update.html +1 -1
- package/docs/functions/_saltcorn_types.ModelAbstracts.abstract_field.instanceOfField.html +1 -1
- package/docs/functions/_saltcorn_types.ModelAbstracts.abstract_page.instanceOfPage.html +1 -1
- package/docs/functions/_saltcorn_types.ModelAbstracts.abstract_view.instanceOfView.html +1 -1
- package/docs/functions/_saltcorn_types.Types.base_types.instanceOWithHtmlFile.html +1 -1
- package/docs/functions/_saltcorn_types.Types.common_types.instanceOfErrorMsg.html +1 -1
- package/docs/functions/_saltcorn_types.Types.common_types.instanceOfSuccessMsg.html +1 -1
- package/docs/functions/_saltcorn_types.Types.common_types.instanceOfType.html +1 -1
- package/docs/functions/_saltcorn_types.generators.generateBool.html +1 -1
- package/docs/functions/_saltcorn_types.generators.generateString.html +1 -1
- package/docs/functions/_saltcorn_types.generators.num_between.html +1 -1
- package/docs/functions/_saltcorn_types.generators.oneOf.html +1 -1
- package/docs/interfaces/_saltcorn_mobile_builder.common_build_utils.ScCapacitorConfig.html +10 -10
- package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_field.AbstractField.html +15 -15
- package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_field.AbstractFieldRepeat.html +3 -3
- package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_form.AbstractForm.html +27 -27
- package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_page.AbstractPage.html +7 -7
- package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_role.AbstractRole.html +3 -3
- package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_table.AbstractTable.html +11 -11
- package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_trigger.AbstractTrigger.html +38 -16
- package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_view.AbstractView.html +10 -10
- package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_workflow.AbstractWorkflow.html +13 -13
- package/docs/modules/_saltcorn_admin_models.backup.html +1 -1
- package/docs/modules/_saltcorn_admin_models.html +1 -1
- package/docs/modules/_saltcorn_admin_models.pack.html +1 -1
- package/docs/modules/_saltcorn_admin_models.tenant.html +1 -1
- package/docs/modules/_saltcorn_common_code.html +1 -1
- package/docs/modules/_saltcorn_data.html +3 -3
- package/docs/modules/_saltcorn_data.models.EventLog.html +2 -2
- package/docs/modules/_saltcorn_data.models.File.html +2 -2
- package/docs/modules/_saltcorn_data.models.Form.html +2 -2
- package/docs/modules/_saltcorn_data.models.PageGroup.html +2 -2
- package/docs/modules/_saltcorn_data.models.Table.html +2 -2
- package/docs/modules/_saltcorn_data.models.View.html +2 -2
- package/docs/modules/_saltcorn_data.models.config.html +1 -1
- package/docs/modules/_saltcorn_data.models.discovery.html +1 -1
- package/docs/modules/_saltcorn_data.models.email.html +1 -1
- package/docs/modules/_saltcorn_data.models.expression.html +1 -1
- package/docs/modules/_saltcorn_data.models.html +1 -1
- package/docs/modules/_saltcorn_data.models.layout.html +1 -1
- package/docs/modules/_saltcorn_data.models.random.html +1 -1
- package/docs/modules/_saltcorn_data.models.scheduler.html +1 -1
- package/docs/modules/_saltcorn_data.plugin_helper.html +1 -1
- package/docs/modules/_saltcorn_data.utils.html +1 -1
- package/docs/modules/_saltcorn_db_common.html +4 -2
- package/docs/modules/_saltcorn_db_common.multi_tenant.html +2 -1
- package/docs/modules/_saltcorn_markup.html +2 -2
- package/docs/modules/_saltcorn_mobile_builder.common_build_utils.html +1 -1
- package/docs/modules/_saltcorn_mobile_builder.html +1 -1
- package/docs/modules/_saltcorn_mobile_builder.package_bundle_utils.html +1 -1
- package/docs/modules/_saltcorn_sqlite.html +1 -1
- package/docs/modules/_saltcorn_sqlite_mobile.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_field.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_form.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_library.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_page.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_plugin.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_role.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_table.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_trigger.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_view.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_workflow.html +1 -1
- package/docs/modules/_saltcorn_types.ModelAbstracts.html +1 -1
- package/docs/modules/_saltcorn_types.Types.base_types.html +1 -1
- package/docs/modules/_saltcorn_types.Types.common_types.html +1 -1
- package/docs/modules/_saltcorn_types.Types.html +1 -1
- package/docs/modules/_saltcorn_types.generators.html +1 -1
- package/docs/modules/_saltcorn_types.html +1 -1
- package/docs/types/_saltcorn_data.models.EventLog.EventLogCfg.html +1 -1
- package/docs/types/_saltcorn_data.models.File.FileCfg.html +1 -1
- package/docs/types/_saltcorn_data.models.Form.AdditionalButton.html +1 -1
- package/docs/types/_saltcorn_data.models.Form.FormCfg.html +1 -1
- package/docs/types/_saltcorn_data.models.PageGroup.ScreenInfoParams.html +1 -1
- package/docs/types/_saltcorn_data.models.Table.ChildRelations.html +1 -1
- package/docs/types/_saltcorn_data.models.Table.ParentRelations.html +1 -1
- package/docs/types/_saltcorn_data.models.Table.RelationData.html +1 -1
- package/docs/types/_saltcorn_data.models.View.FindViewsPred.html +1 -1
- package/docs/types/_saltcorn_db_common.AggregationOptions.html +2 -1
- package/docs/types/_saltcorn_db_common.CoordOpts.html +2 -1
- package/docs/types/_saltcorn_db_common.DatabaseClient.html +2 -1
- package/docs/types/_saltcorn_db_common.JoinField.html +2 -1
- package/docs/types/_saltcorn_db_common.JoinFields.html +2 -1
- package/docs/types/_saltcorn_db_common.JoinOptions.html +2 -1
- package/docs/types/_saltcorn_db_common.JsonPath.html +2 -1
- package/docs/types/_saltcorn_db_common.JsonPathElem.html +2 -1
- package/docs/types/_saltcorn_db_common.Operator.html +2 -1
- package/docs/types/_saltcorn_db_common.PartialSome.html +2 -1
- package/docs/types/_saltcorn_db_common.PrimaryKeyValue.html +2 -1
- package/docs/types/_saltcorn_db_common.Row.html +2 -1
- package/docs/types/_saltcorn_db_common.SelectOptions.html +2 -1
- package/docs/types/_saltcorn_db_common.SqlAndValues.html +2 -1
- package/docs/types/_saltcorn_db_common.StrongRow.html +2 -1
- package/docs/types/_saltcorn_db_common.SubselectOptions.html +2 -1
- package/docs/types/_saltcorn_db_common.Value.html +2 -1
- package/docs/types/_saltcorn_db_common.Where.html +2 -1
- package/docs/types/_saltcorn_mobile_builder.IosCfg.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_field.FieldCfg.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_field.InputType.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_form.AdditionalButton.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_library.LibraryCfg.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_library.LibraryPack.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_page.PageCfg.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_page.PagePack.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_plugin.PluginCfg.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_plugin.PluginPack.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_role.RoleCfg.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_role.RolePack.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_table.TableCfg.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_table.TablePack.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_trigger.TriggerCfg.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_trigger.TriggerPack.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_view.ViewCfg.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_view.ViewPack.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_workflow.ConfigWorkflowStep.html +1 -1
- package/docs/types/_saltcorn_types.ModelAbstracts.abstract_workflow.RunResult.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.Action.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.AuthenticationMethod.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.CalcJoinfield.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.CapacitorPlugin.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.CodePagePack.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.Column.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.ConnectObjType.html +4 -2
- package/docs/types/_saltcorn_types.Types.base_types.ConnectedObjects.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.CopilotSkill.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.ErrorObj.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.FieldLike.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.FieldView.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.Header.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.JoinFieldOption.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.Layout.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.MobileConfig.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.ModelPattern.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.Pack.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.Plugin.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.PluginFunction.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.PluginLayout.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.PluginRoute.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.PluginSourceType.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.PluginType.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.PluginWrap.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.PluginWrapArg.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.RelationOption.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.Req.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.Res.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.ResultType.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.RouteAction.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.RunExtra.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.SlugStepType.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.StepResType.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.SubField.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.TableProvider.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.TableQuery.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.Tablely.html +1 -1
- package/docs/types/_saltcorn_types.Types.base_types.ViewTemplate.html +1 -1
- package/docs/types/_saltcorn_types.Types.common_types.ErrorMessage.html +1 -1
- package/docs/types/_saltcorn_types.Types.common_types.GenObj.html +1 -1
- package/docs/types/_saltcorn_types.Types.common_types.ReqRes.html +1 -1
- package/docs/types/_saltcorn_types.Types.common_types.ResultMessage.html +1 -1
- package/docs/types/_saltcorn_types.Types.common_types.SuccessMessage.html +1 -1
- package/docs/types/_saltcorn_types.Types.common_types.Type.html +1 -1
- package/docs/variables/_saltcorn_data.db.html +1 -1
- package/docs/variables/_saltcorn_data.migrations.html +1 -1
- package/docs/variables/_saltcorn_data.models.config.available_languages.html +1 -1
- package/docs/variables/_saltcorn_data.models.config.configTypes.html +1 -1
- package/docs/variables/_saltcorn_data.models.scheduler.runScheduler.html +1 -1
- package/docs/variables/_saltcorn_data.plugin_helper.run_action_column.html +1 -1
- package/docs/variables/_saltcorn_data.utils.NotAuthorized.html +1 -1
- package/docs/variables/_saltcorn_data.utils.isPushEnabled.html +1 -1
- package/docs/variables/_saltcorn_data.utils.sleep.html +1 -1
- package/docs/variables/_saltcorn_db_common.multi_tenant.tenantNamespace.html +2 -1
- package/help/JavaScript action code.tmd +10 -0
- package/locales/en.json +32 -1
- package/package.json +9 -9
- package/public/log_viewer_utils.js +3 -2
- package/public/saltcorn-common.js +89 -39
- package/public/saltcorn.css +12 -0
- package/public/saltcorn.js +8 -0
- package/routes/actions.js +14 -0
- package/routes/admin.js +5 -3
- package/routes/common_lists.js +8 -1
- package/routes/eventlog.js +20 -0
- package/routes/fields.js +1 -1
- package/routes/menu.js +98 -6
- package/routes/page.js +4 -1
- package/routes/pageedit.js +1 -0
- package/routes/plugins.js +8 -7
- package/routes/tables.js +11 -0
- package/routes/view.js +12 -3
- package/serve.js +76 -13
- package/tests/admin.test.js +3 -3
- package/tests/auth.test.js +1 -0
- package/tests/viewedit.test.js +2 -0
- package/wrapper.js +24 -192
package/routes/actions.js
CHANGED
|
@@ -179,6 +179,7 @@ const triggerForm = async (req, trigger) => {
|
|
|
179
179
|
workflow: true,
|
|
180
180
|
});
|
|
181
181
|
const table_triggers = ["Insert", "Update", "Delete", "Validate"];
|
|
182
|
+
const additional_triggers_with_onlyif = ["Login", "PageLoad"];
|
|
182
183
|
const action_options = {};
|
|
183
184
|
const actionsNotRequiringRow = Trigger.action_options({
|
|
184
185
|
notRequireRow: true,
|
|
@@ -337,6 +338,19 @@ const triggerForm = async (req, trigger) => {
|
|
|
337
338
|
type: "String",
|
|
338
339
|
showIf: { when_trigger: ["API call"], _raw_output: true },
|
|
339
340
|
},
|
|
341
|
+
{
|
|
342
|
+
name: "_only_if",
|
|
343
|
+
label: req.__("Only if"),
|
|
344
|
+
type: "String",
|
|
345
|
+
class: "validate-expression",
|
|
346
|
+
sublabel: req.__(
|
|
347
|
+
"Optional JavaScript expression to determine if the trigger should run."
|
|
348
|
+
),
|
|
349
|
+
parent_field: "configuration",
|
|
350
|
+
showIf: {
|
|
351
|
+
when_trigger: [...table_triggers, ...additional_triggers_with_onlyif],
|
|
352
|
+
},
|
|
353
|
+
},
|
|
340
354
|
],
|
|
341
355
|
});
|
|
342
356
|
// if (trigger) {
|
package/routes/admin.js
CHANGED
|
@@ -500,11 +500,12 @@ router.get(
|
|
|
500
500
|
"backup_s3_access_secret"
|
|
501
501
|
);
|
|
502
502
|
backupForm.values.backup_s3_region =
|
|
503
|
-
|
|
503
|
+
getState().getConfig("backup_s3_region");
|
|
504
504
|
aBackupFilePrefixForm.values.backup_with_event_log = getState().getConfig(
|
|
505
505
|
"backup_with_event_log"
|
|
506
506
|
);
|
|
507
|
-
aBackupFilePrefixForm.values.backup_password =
|
|
507
|
+
aBackupFilePrefixForm.values.backup_password =
|
|
508
|
+
getState().getConfig("backup_password");
|
|
508
509
|
const aSnapshotForm = snapshotForm(req);
|
|
509
510
|
aSnapshotForm.values.snapshots_enabled =
|
|
510
511
|
getState().getConfig("snapshots_enabled");
|
|
@@ -4126,6 +4127,8 @@ router.post(
|
|
|
4126
4127
|
await db.deleteWhere("_sc_config", { not: { key: "letsencrypt" } });
|
|
4127
4128
|
}
|
|
4128
4129
|
await getState().refresh();
|
|
4130
|
+
await require("@saltcorn/data/standard-menu")();
|
|
4131
|
+
|
|
4129
4132
|
if (form.values.users) {
|
|
4130
4133
|
await db.deleteWhere("_sc_notifications");
|
|
4131
4134
|
|
|
@@ -4532,7 +4535,6 @@ admin_config_route({
|
|
|
4532
4535
|
path: "/notifications",
|
|
4533
4536
|
super_path: "/admin",
|
|
4534
4537
|
field_names: [
|
|
4535
|
-
"notification_in_menu",
|
|
4536
4538
|
{ section_header: "Progressive Web Application" },
|
|
4537
4539
|
"pwa_enabled",
|
|
4538
4540
|
{ name: "pwa_display", showIf: { pwa_enabled: true } },
|
package/routes/common_lists.js
CHANGED
|
@@ -138,6 +138,7 @@ const tablesList = async (
|
|
|
138
138
|
hover: true,
|
|
139
139
|
tableClass: listClass(tagId, showList),
|
|
140
140
|
tableId: domId,
|
|
141
|
+
class: "table-valign-middle",
|
|
141
142
|
}
|
|
142
143
|
) +
|
|
143
144
|
(tables.length == 0 && !filterOnTag
|
|
@@ -442,6 +443,7 @@ const viewsList = async (
|
|
|
442
443
|
hover: true,
|
|
443
444
|
tableClass: listClass(tagId, showList),
|
|
444
445
|
tableId: domId,
|
|
446
|
+
class: "table-valign-middle",
|
|
445
447
|
}
|
|
446
448
|
) +
|
|
447
449
|
(views.length == 0 && !filterOnTag
|
|
@@ -625,6 +627,7 @@ const getPageList = async (
|
|
|
625
627
|
hover: true,
|
|
626
628
|
tableClass: tagId ? `collapse ${showList ? "show" : ""}` : "",
|
|
627
629
|
tableId: domId,
|
|
630
|
+
class: "table-valign-middle",
|
|
628
631
|
}
|
|
629
632
|
);
|
|
630
633
|
};
|
|
@@ -657,6 +660,7 @@ const getPageGroupList = (rows, roles, req) => {
|
|
|
657
660
|
rows,
|
|
658
661
|
{
|
|
659
662
|
hover: true,
|
|
663
|
+
class: "table-valign-middle",
|
|
660
664
|
}
|
|
661
665
|
);
|
|
662
666
|
};
|
|
@@ -729,6 +733,8 @@ const getTriggerList = async (
|
|
|
729
733
|
)
|
|
730
734
|
);
|
|
731
735
|
};
|
|
736
|
+
const whenCanHaveTable = (when) =>
|
|
737
|
+
["Insert", "Update", "Delete", "Validate", "Never"].includes(when);
|
|
732
738
|
return mkTable(
|
|
733
739
|
[
|
|
734
740
|
{ label: req.__("Name"), key: "name" },
|
|
@@ -781,7 +787,7 @@ const getTriggerList = async (
|
|
|
781
787
|
{
|
|
782
788
|
label: req.__("Table or Channel"),
|
|
783
789
|
key: (r) =>
|
|
784
|
-
r.table_name
|
|
790
|
+
r.table_name && whenCanHaveTable(r.when_trigger)
|
|
785
791
|
? user_can_inspect_tables
|
|
786
792
|
? a({ href: `/table/${r.table_name}` }, r.table_name)
|
|
787
793
|
: r.table_name
|
|
@@ -807,6 +813,7 @@ const getTriggerList = async (
|
|
|
807
813
|
hover: true,
|
|
808
814
|
tableClass: tagId ? `collapse ${showList ? "show" : ""}` : "",
|
|
809
815
|
tableId: domId,
|
|
816
|
+
class: "table-valign-middle",
|
|
810
817
|
}
|
|
811
818
|
);
|
|
812
819
|
};
|
package/routes/eventlog.js
CHANGED
|
@@ -81,6 +81,18 @@ const logSettingsForm = async (req) => {
|
|
|
81
81
|
input_type: "date",
|
|
82
82
|
attributes: { minDate: new Date(), maxDate: hoursFuture(24 * 7 * 2) },
|
|
83
83
|
},
|
|
84
|
+
{
|
|
85
|
+
input_type: "section_header",
|
|
86
|
+
label: req.__("Dynamic server side updates"),
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "enable_dynamic_updates",
|
|
90
|
+
label: req.__("Enable dynamic updates"),
|
|
91
|
+
type: "Bool",
|
|
92
|
+
sublabel: req.__(
|
|
93
|
+
"Enable server side updates from within run_js_code actions"
|
|
94
|
+
),
|
|
95
|
+
},
|
|
84
96
|
{
|
|
85
97
|
input_type: "section_header",
|
|
86
98
|
label: req.__("Delete old workflow runs with status after days"),
|
|
@@ -168,6 +180,10 @@ router.get(
|
|
|
168
180
|
"next_weekly_event",
|
|
169
181
|
{}
|
|
170
182
|
);
|
|
183
|
+
form.values.enable_dynamic_updates = getState().getConfig(
|
|
184
|
+
"enable_dynamic_updates",
|
|
185
|
+
true
|
|
186
|
+
);
|
|
171
187
|
["error", "finished", "running", "waiting"].forEach((k) => {
|
|
172
188
|
let cfgk = `delete_${k}_workflows_days`;
|
|
173
189
|
form.values[cfgk] = getState().getConfig(cfgk);
|
|
@@ -377,6 +393,10 @@ router.post(
|
|
|
377
393
|
delete form.values[k];
|
|
378
394
|
}
|
|
379
395
|
}
|
|
396
|
+
await getState().setConfig(
|
|
397
|
+
"enable_dynamic_updates",
|
|
398
|
+
form.values.enable_dynamic_updates
|
|
399
|
+
);
|
|
380
400
|
for (const status of ["error", "finished", "running", "waiting"]) {
|
|
381
401
|
let k = `delete_${status}_workflows_days`;
|
|
382
402
|
if (form.values[k]) {
|
package/routes/fields.js
CHANGED
|
@@ -1530,7 +1530,7 @@ router.post(
|
|
|
1530
1530
|
const table = Table.findOne({ name: table_name });
|
|
1531
1531
|
const field = table.getField(field_name);
|
|
1532
1532
|
let val = field.type?.read
|
|
1533
|
-
? field.type?.read(req.body[field_name])
|
|
1533
|
+
? field.type?.read(req.body[field_name], field.attributes)
|
|
1534
1534
|
: req.body[field_name];
|
|
1535
1535
|
await db.withTransaction(async () => {
|
|
1536
1536
|
await table.updateRow({ [field_name]: val }, pk, req.user);
|
package/routes/menu.js
CHANGED
|
@@ -119,6 +119,8 @@ const menuForm = async (req) => {
|
|
|
119
119
|
"View",
|
|
120
120
|
"Page",
|
|
121
121
|
"Page Group",
|
|
122
|
+
"Admin Page",
|
|
123
|
+
"User Page",
|
|
122
124
|
"Link",
|
|
123
125
|
"Header",
|
|
124
126
|
"Dynamic",
|
|
@@ -150,6 +152,39 @@ const menuForm = async (req) => {
|
|
|
150
152
|
options: pages.map((r) => r.name),
|
|
151
153
|
showIf: { type: "Page" },
|
|
152
154
|
},
|
|
155
|
+
{
|
|
156
|
+
name: "admin_page",
|
|
157
|
+
label: req.__("Admin Page"),
|
|
158
|
+
input_type: "select",
|
|
159
|
+
class: "item-menu",
|
|
160
|
+
options: [
|
|
161
|
+
"Tables",
|
|
162
|
+
"Views",
|
|
163
|
+
"Pages",
|
|
164
|
+
"About application",
|
|
165
|
+
"Modules",
|
|
166
|
+
"Users and security",
|
|
167
|
+
"Site structure",
|
|
168
|
+
"Files",
|
|
169
|
+
"Events",
|
|
170
|
+
"Settings",
|
|
171
|
+
],
|
|
172
|
+
showIf: { type: "Admin Page" },
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: "user_page",
|
|
176
|
+
label: req.__("User Page"),
|
|
177
|
+
input_type: "select",
|
|
178
|
+
class: "item-menu",
|
|
179
|
+
options: [
|
|
180
|
+
"Notifications",
|
|
181
|
+
"User settings",
|
|
182
|
+
"Login",
|
|
183
|
+
"Logout",
|
|
184
|
+
"Signup",
|
|
185
|
+
],
|
|
186
|
+
showIf: { type: "User Page" },
|
|
187
|
+
},
|
|
153
188
|
{
|
|
154
189
|
name: "viewname",
|
|
155
190
|
label: req.__("View"),
|
|
@@ -247,6 +282,16 @@ const menuForm = async (req) => {
|
|
|
247
282
|
required: true,
|
|
248
283
|
showIf: { type: "Dynamic" },
|
|
249
284
|
},
|
|
285
|
+
{
|
|
286
|
+
name: "user_menu_header",
|
|
287
|
+
label: req.__("User menu header"),
|
|
288
|
+
sublabel: req.__("Some themes display this header differently"),
|
|
289
|
+
type: "Bool",
|
|
290
|
+
class: "item-menu",
|
|
291
|
+
required: false,
|
|
292
|
+
default: false,
|
|
293
|
+
showIf: { type: "Header" },
|
|
294
|
+
},
|
|
250
295
|
{
|
|
251
296
|
name: "text",
|
|
252
297
|
label: req.__("Text label"),
|
|
@@ -263,6 +308,8 @@ const menuForm = async (req) => {
|
|
|
263
308
|
"Dynamic",
|
|
264
309
|
"Search",
|
|
265
310
|
"Action",
|
|
311
|
+
"Admin Page",
|
|
312
|
+
"User Page",
|
|
266
313
|
],
|
|
267
314
|
},
|
|
268
315
|
},
|
|
@@ -274,7 +321,16 @@ const menuForm = async (req) => {
|
|
|
274
321
|
html: `<button type="button" id="myEditor_icon" class="btn btn-outline-secondary"></button>`,
|
|
275
322
|
},
|
|
276
323
|
showIf: {
|
|
277
|
-
type: [
|
|
324
|
+
type: [
|
|
325
|
+
"View",
|
|
326
|
+
"Page",
|
|
327
|
+
"Page Group",
|
|
328
|
+
"Link",
|
|
329
|
+
"Header",
|
|
330
|
+
"Action",
|
|
331
|
+
"Admin Page",
|
|
332
|
+
"User Page",
|
|
333
|
+
],
|
|
278
334
|
},
|
|
279
335
|
},
|
|
280
336
|
{
|
|
@@ -282,7 +338,16 @@ const menuForm = async (req) => {
|
|
|
282
338
|
class: "item-menu",
|
|
283
339
|
input_type: "hidden",
|
|
284
340
|
showIf: {
|
|
285
|
-
type: [
|
|
341
|
+
type: [
|
|
342
|
+
"View",
|
|
343
|
+
"Page",
|
|
344
|
+
"Page Group",
|
|
345
|
+
"Link",
|
|
346
|
+
"Header",
|
|
347
|
+
"Action",
|
|
348
|
+
"Admin Page",
|
|
349
|
+
"User Page",
|
|
350
|
+
],
|
|
286
351
|
},
|
|
287
352
|
},
|
|
288
353
|
{
|
|
@@ -301,6 +366,8 @@ const menuForm = async (req) => {
|
|
|
301
366
|
"Dynamic",
|
|
302
367
|
"Search",
|
|
303
368
|
"Action",
|
|
369
|
+
"Admin Page",
|
|
370
|
+
"User Page",
|
|
304
371
|
],
|
|
305
372
|
},
|
|
306
373
|
},
|
|
@@ -343,7 +410,16 @@ const menuForm = async (req) => {
|
|
|
343
410
|
type: "Bool",
|
|
344
411
|
required: false,
|
|
345
412
|
class: "item-menu",
|
|
346
|
-
showIf: {
|
|
413
|
+
showIf: {
|
|
414
|
+
type: [
|
|
415
|
+
"View",
|
|
416
|
+
"Page",
|
|
417
|
+
"Page Group",
|
|
418
|
+
"Link",
|
|
419
|
+
"Admin Page",
|
|
420
|
+
"User Page",
|
|
421
|
+
],
|
|
422
|
+
},
|
|
347
423
|
},
|
|
348
424
|
{
|
|
349
425
|
name: "in_modal",
|
|
@@ -351,7 +427,16 @@ const menuForm = async (req) => {
|
|
|
351
427
|
type: "Bool",
|
|
352
428
|
required: false,
|
|
353
429
|
class: "item-menu",
|
|
354
|
-
showIf: {
|
|
430
|
+
showIf: {
|
|
431
|
+
type: [
|
|
432
|
+
"View",
|
|
433
|
+
"Page",
|
|
434
|
+
"Page Group",
|
|
435
|
+
"Link",
|
|
436
|
+
"Admin Page",
|
|
437
|
+
"User Page",
|
|
438
|
+
],
|
|
439
|
+
},
|
|
355
440
|
},
|
|
356
441
|
{
|
|
357
442
|
name: "style",
|
|
@@ -369,6 +454,8 @@ const menuForm = async (req) => {
|
|
|
369
454
|
"Header",
|
|
370
455
|
"Dynamic",
|
|
371
456
|
"Action",
|
|
457
|
+
"Admin Page",
|
|
458
|
+
"User Page",
|
|
372
459
|
],
|
|
373
460
|
},
|
|
374
461
|
attributes: {
|
|
@@ -403,6 +490,8 @@ const menuForm = async (req) => {
|
|
|
403
490
|
"Search",
|
|
404
491
|
"Separator",
|
|
405
492
|
"Action",
|
|
493
|
+
"Admin Page",
|
|
494
|
+
"User Page",
|
|
406
495
|
],
|
|
407
496
|
},
|
|
408
497
|
sublabel: req.__("Not all themes support all locations"),
|
|
@@ -628,14 +717,17 @@ router.post(
|
|
|
628
717
|
"/action/:rndid",
|
|
629
718
|
error_catcher(async (req, res, next) => {
|
|
630
719
|
const state = getState();
|
|
631
|
-
const maintenanceModeEnabled = state.getConfig(
|
|
720
|
+
const maintenanceModeEnabled = state.getConfig(
|
|
721
|
+
"maintenance_mode_enabled",
|
|
722
|
+
false
|
|
723
|
+
);
|
|
632
724
|
|
|
633
725
|
if (maintenanceModeEnabled && (!req.user || req.user.role_id > 1)) {
|
|
634
726
|
res.status(503).json({ error: "in maintenance mode" });
|
|
635
727
|
return;
|
|
636
728
|
}
|
|
637
729
|
next();
|
|
638
|
-
})
|
|
730
|
+
})
|
|
639
731
|
);
|
|
640
732
|
|
|
641
733
|
const getIcons = () => {
|
package/routes/page.js
CHANGED
|
@@ -46,18 +46,21 @@ const findPageOrGroup = (pagename) => {
|
|
|
46
46
|
|
|
47
47
|
const runPage = async (page, req, res, tic) => {
|
|
48
48
|
const role = req.user && req.user.id ? req.user.role_id : 100;
|
|
49
|
+
// let resultCollector = {};
|
|
49
50
|
if (role <= page.min_role) {
|
|
50
51
|
const contents = await page.run(req.query, { res, req });
|
|
51
52
|
const title = scan_for_page_title(contents, page.title);
|
|
52
53
|
const tock = new Date();
|
|
53
54
|
const ms = tock.getTime() - tic.getTime();
|
|
54
|
-
|
|
55
|
+
|
|
56
|
+
if (!isTest()) {
|
|
55
57
|
Trigger.emitEvent("PageLoad", null, req.user, {
|
|
56
58
|
text: req.__("Page '%s' was loaded", page.name),
|
|
57
59
|
type: "page",
|
|
58
60
|
name: page.name,
|
|
59
61
|
render_time: ms,
|
|
60
62
|
});
|
|
63
|
+
}
|
|
61
64
|
if (contents.html_file) await sendHtmlFile(req, res, contents.html_file);
|
|
62
65
|
else
|
|
63
66
|
res.sendWrap(
|
package/routes/pageedit.js
CHANGED
package/routes/plugins.js
CHANGED
|
@@ -238,7 +238,7 @@ const cfg_link = (req, row) => {
|
|
|
238
238
|
if (plugin.configuration_workflow)
|
|
239
239
|
return a(
|
|
240
240
|
{
|
|
241
|
-
class: "btn btn-secondary btn-sm d-inline
|
|
241
|
+
class: "btn btn-secondary btn-sm d-inline-block",
|
|
242
242
|
role: "button",
|
|
243
243
|
href: `/plugins/configure/${encodeURIComponent(row.name)}`,
|
|
244
244
|
title: req.__("Configure plugin"),
|
|
@@ -256,7 +256,7 @@ const cfg_link = (req, row) => {
|
|
|
256
256
|
const info_link = (req, row) =>
|
|
257
257
|
a(
|
|
258
258
|
{
|
|
259
|
-
class: "btn btn-secondary btn-sm d-inline",
|
|
259
|
+
class: "btn btn-secondary btn-sm d-inline-block me-1",
|
|
260
260
|
role: "button",
|
|
261
261
|
href: `/plugins/info/${encodeURIComponent(row.name)}`,
|
|
262
262
|
title: req.__("Information about plugin"),
|
|
@@ -306,7 +306,7 @@ const store_item_html = (req) => (item) => ({
|
|
|
306
306
|
!item.installed &&
|
|
307
307
|
item.plugin &&
|
|
308
308
|
div(
|
|
309
|
-
{ class: "
|
|
309
|
+
{ class: "d-inline" },
|
|
310
310
|
post_btn(
|
|
311
311
|
`/plugins/install/${encodeURIComponent(item.name)}`,
|
|
312
312
|
req.__("Install"),
|
|
@@ -331,10 +331,11 @@ const store_item_html = (req) => (item) => ({
|
|
|
331
331
|
onClick: "press_store_button(this)",
|
|
332
332
|
}
|
|
333
333
|
),
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
334
|
+
div(
|
|
335
|
+
{ class: "btn-group", role: "group" },
|
|
336
|
+
item.installed && item.plugin && cfg_link(req, item),
|
|
337
|
+
item.installed && item.plugin && info_link(req, item)
|
|
338
|
+
),
|
|
338
339
|
item.installed &&
|
|
339
340
|
item.pack &&
|
|
340
341
|
post_btn(
|
package/routes/tables.js
CHANGED
|
@@ -1309,6 +1309,17 @@ router.post(
|
|
|
1309
1309
|
} else rest.ownership_formula = null;
|
|
1310
1310
|
await db.withTransaction(async () => {
|
|
1311
1311
|
await table.update(rest);
|
|
1312
|
+
// Update table field's min_role_write attributes
|
|
1313
|
+
const fields = table.getFields();
|
|
1314
|
+
|
|
1315
|
+
for (const f of fields) {
|
|
1316
|
+
if (f.attributes?.min_role_write) {
|
|
1317
|
+
f.attributes.min_role_write = parseInt(rest.min_role_write);
|
|
1318
|
+
await f.update({
|
|
1319
|
+
attributes: f.attributes,
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1312
1323
|
});
|
|
1313
1324
|
await getState().refresh_tables();
|
|
1314
1325
|
if (!req.xhr) {
|
package/routes/view.js
CHANGED
|
@@ -43,7 +43,10 @@ router.get(
|
|
|
43
43
|
["/:viewname", "/:viewname/*slug"],
|
|
44
44
|
error_catcher(async (req, res) => {
|
|
45
45
|
const state = getState();
|
|
46
|
-
const maintenanceModeEnabled = state.getConfig(
|
|
46
|
+
const maintenanceModeEnabled = state.getConfig(
|
|
47
|
+
"maintenance_mode_enabled",
|
|
48
|
+
false
|
|
49
|
+
);
|
|
47
50
|
const maintenanceModePage = state.getConfig("maintenance_mode_page", "");
|
|
48
51
|
|
|
49
52
|
if (
|
|
@@ -242,7 +245,10 @@ router.post(
|
|
|
242
245
|
"/:viewname/:route",
|
|
243
246
|
error_catcher(async (req, res, next) => {
|
|
244
247
|
const state = getState();
|
|
245
|
-
const maintenanceModeEnabled = state.getConfig(
|
|
248
|
+
const maintenanceModeEnabled = state.getConfig(
|
|
249
|
+
"maintenance_mode_enabled",
|
|
250
|
+
false
|
|
251
|
+
);
|
|
246
252
|
|
|
247
253
|
if (maintenanceModeEnabled && (!req.user || req.user.role_id > 1)) {
|
|
248
254
|
res.status(503).json({ error: "in maintenance mode" });
|
|
@@ -287,7 +293,10 @@ router.post(
|
|
|
287
293
|
["/:viewname", "/:viewname/*slug"],
|
|
288
294
|
error_catcher(async (req, res, next) => {
|
|
289
295
|
const state = getState();
|
|
290
|
-
const maintenanceModeEnabled = state.getConfig(
|
|
296
|
+
const maintenanceModeEnabled = state.getConfig(
|
|
297
|
+
"maintenance_mode_enabled",
|
|
298
|
+
false
|
|
299
|
+
);
|
|
291
300
|
if (maintenanceModeEnabled && (!req.user || req.user.role_id > 1)) {
|
|
292
301
|
res.status(503).send("Page Unavailable: in maintenance mode");
|
|
293
302
|
return;
|
package/serve.js
CHANGED
|
@@ -290,7 +290,8 @@ const onMessageFromWorker =
|
|
|
290
290
|
///ie from saltcorn
|
|
291
291
|
//broadcast
|
|
292
292
|
Object.entries(cluster.workers).forEach(([wpid, w]) => {
|
|
293
|
-
if
|
|
293
|
+
//if it is plugin refresh, we need sender to get it as wll
|
|
294
|
+
if (wpid !== pid || msg?.refresh_plugin_cfg) w.send(msg);
|
|
294
295
|
});
|
|
295
296
|
workerDispatchMsg(msg); //also master
|
|
296
297
|
return true;
|
|
@@ -382,6 +383,13 @@ module.exports =
|
|
|
382
383
|
masterState.listeningTo.add(id);
|
|
383
384
|
}
|
|
384
385
|
});
|
|
386
|
+
getState().sendMessageToWorkers = (msg) => {
|
|
387
|
+
Object.entries(cluster.workers).forEach(([wpid, w]) => {
|
|
388
|
+
w.send(msg);
|
|
389
|
+
});
|
|
390
|
+
workerDispatchMsg(msg); //also master
|
|
391
|
+
};
|
|
392
|
+
|
|
385
393
|
if (masterState.listeningTo.size < useNCpus)
|
|
386
394
|
setTimeout(initMasterListeners, 250);
|
|
387
395
|
};
|
|
@@ -420,12 +428,21 @@ module.exports =
|
|
|
420
428
|
|
|
421
429
|
if (forkAnyWorkers) {
|
|
422
430
|
for (let i = 0; i < useNCpus; i++) addWorker(cluster.fork());
|
|
431
|
+
getState().sendMessageToWorkers = (msg) => {
|
|
432
|
+
Object.entries(cluster.workers).forEach(([wpid, w]) => {
|
|
433
|
+
w.send(msg);
|
|
434
|
+
});
|
|
435
|
+
workerDispatchMsg(msg); //also master
|
|
436
|
+
};
|
|
423
437
|
|
|
424
438
|
cluster.on("exit", (worker, code, signal) => {
|
|
425
439
|
console.log(`worker ${worker.process.pid} died`);
|
|
426
440
|
addWorker(cluster.fork());
|
|
427
441
|
});
|
|
428
442
|
} else {
|
|
443
|
+
getState().sendMessageToWorkers = (msg) => {
|
|
444
|
+
workerDispatchMsg(msg); //also master
|
|
445
|
+
};
|
|
429
446
|
await nonGreenlockWorkerSetup(appargs, port, host);
|
|
430
447
|
runScheduler({
|
|
431
448
|
port,
|
|
@@ -544,11 +561,26 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
544
561
|
.emit("log_msg", { text: msg, time, level });
|
|
545
562
|
});
|
|
546
563
|
|
|
547
|
-
// Real-time collaboration emitter
|
|
564
|
+
// Real-time collaboration emitter (tied to views)
|
|
548
565
|
getState().setCollabEmitter((tenant, type, data) => {
|
|
549
566
|
io.of("/").to(`_${tenant}_collab_room_`).emit(type, data);
|
|
550
567
|
});
|
|
551
568
|
|
|
569
|
+
// dynamic updates emitter (for run_js_actions)
|
|
570
|
+
getState().setDynamicUpdateEmitter((tenant, data, userIds) => {
|
|
571
|
+
if (userIds) {
|
|
572
|
+
for (const userId of userIds) {
|
|
573
|
+
io.of("/")
|
|
574
|
+
.to(`_${tenant}:${userId}_dynamic_update_room`)
|
|
575
|
+
.emit("dynamic_update", data);
|
|
576
|
+
}
|
|
577
|
+
} else {
|
|
578
|
+
io.of("/")
|
|
579
|
+
.to(`_${tenant}_dynamic_update_room`)
|
|
580
|
+
.emit("dynamic_update", data);
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
|
|
552
584
|
io.of("/").on("connection", (socket) => {
|
|
553
585
|
socket.on("join_room", ([viewname, room_id]) => {
|
|
554
586
|
const ten = get_tenant_from_req(socket.request) || "public";
|
|
@@ -596,7 +628,7 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
596
628
|
callback({ status: "error", msg: err.message || "unknown error" });
|
|
597
629
|
}
|
|
598
630
|
};
|
|
599
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
631
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
600
632
|
else await f();
|
|
601
633
|
});
|
|
602
634
|
|
|
@@ -620,7 +652,30 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
620
652
|
callback({ status: "error", msg: err.message || "unknown error" });
|
|
621
653
|
}
|
|
622
654
|
};
|
|
623
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
655
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
656
|
+
else await f();
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
// join_dynamic_update_room for events emitted from run_js_actions
|
|
660
|
+
socket.on("join_dynamic_update_room", async (callback) => {
|
|
661
|
+
const tenant =
|
|
662
|
+
get_tenant_from_req(socket.request, subdomainOffset) || "public";
|
|
663
|
+
const f = async () => {
|
|
664
|
+
try {
|
|
665
|
+
const enabled = getState().getConfig("enable_dynamic_updates", true);
|
|
666
|
+
if (!enabled) throw new Error("Dynamic updates are not enabled");
|
|
667
|
+
const user = socket.request.user;
|
|
668
|
+
if (!user) throw new Error("Not authorized");
|
|
669
|
+
socket.join(`_${tenant}_dynamic_update_room`);
|
|
670
|
+
socket.join(`_${tenant}:${user.id}_dynamic_update_room`);
|
|
671
|
+
if (typeof callback === "function") callback({ status: "ok" });
|
|
672
|
+
} catch (err) {
|
|
673
|
+
getState().log(1, `Socket join_dynamic_update_room: ${err.stack}`);
|
|
674
|
+
if (typeof callback === "function")
|
|
675
|
+
callback({ status: "error", msg: err.message || "unknown error" });
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
624
679
|
else await f();
|
|
625
680
|
});
|
|
626
681
|
|
|
@@ -628,12 +683,20 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
628
683
|
const tenant =
|
|
629
684
|
get_tenant_from_req(socket.request, subdomainOffset) || "public";
|
|
630
685
|
const f = async () => {
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
|
|
686
|
+
const state = getState();
|
|
687
|
+
if (state) {
|
|
688
|
+
const socketIds = state.getConfig("joined_log_socket_ids");
|
|
689
|
+
const newSocketIds = socketIds.filter((id) => id !== socket.id);
|
|
690
|
+
await state.setConfig("joined_log_socket_ids", newSocketIds);
|
|
691
|
+
} else {
|
|
692
|
+
console.error("No state found in socket disconnect");
|
|
693
|
+
console.error("The current tenantSchema is:", db.getTenantSchema());
|
|
694
|
+
console.error("The current tenant from request is:", tenant);
|
|
695
|
+
console.error("node version:", process.version);
|
|
696
|
+
}
|
|
634
697
|
};
|
|
635
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
636
|
-
else f();
|
|
698
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
699
|
+
else await f();
|
|
637
700
|
});
|
|
638
701
|
});
|
|
639
702
|
|
|
@@ -681,8 +744,8 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
681
744
|
callback({ status: "error", msg: err.message || "unknown error" });
|
|
682
745
|
}
|
|
683
746
|
};
|
|
684
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
685
|
-
else f();
|
|
747
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
748
|
+
else await f();
|
|
686
749
|
}
|
|
687
750
|
);
|
|
688
751
|
socket.on("write_to_stream", async (data, callback) => {
|
|
@@ -744,8 +807,8 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
744
807
|
}
|
|
745
808
|
});
|
|
746
809
|
};
|
|
747
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
748
|
-
else f();
|
|
810
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
811
|
+
else await f();
|
|
749
812
|
});
|
|
750
813
|
});
|
|
751
814
|
};
|
package/tests/admin.test.js
CHANGED
|
@@ -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/
|
|
390
|
+
.expect(toRedirect("/actions/configure/7"));
|
|
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/
|
|
454
|
+
.expect(toRedirect("/actions/configure/8"));
|
|
455
455
|
await request(app)
|
|
456
|
-
.post("/actions/configure/
|
|
456
|
+
.post("/actions/configure/8")
|
|
457
457
|
.set("Cookie", loginCookie)
|
|
458
458
|
.send("code=return 27")
|
|
459
459
|
.expect(toRedirect("/actions/"));
|
package/tests/auth.test.js
CHANGED
|
@@ -166,6 +166,7 @@ describe("AuthTest forgot password", () => {
|
|
|
166
166
|
.post("/auth/reset")
|
|
167
167
|
.send("email=staff1@foo.com")
|
|
168
168
|
.send("password=bazzRGGR65zoo")
|
|
169
|
+
.send("confirm_password=bazzRGGR65zoo")
|
|
169
170
|
.send("token=" + token)
|
|
170
171
|
.expect(toRedirect("/auth/login"));
|
|
171
172
|
await request(app)
|