@saltcorn/server 1.3.1-beta.0 → 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/roleadmin.js +54 -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 +27 -27
- 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 +3 -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 +11 -3
- 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 +2 -1
- package/docs/variables/_saltcorn_data.utils.isPushEnabled.html +67 -0
- package/docs/variables/_saltcorn_data.utils.sleep.html +2 -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 +100 -31
- package/public/saltcorn.css +16 -0
- package/public/saltcorn.js +8 -0
- package/routes/actions.js +17 -1
- package/routes/admin.js +5 -3
- package/routes/common_lists.js +8 -1
- package/routes/eventlog.js +20 -0
- package/routes/fields.js +10 -2
- package/routes/menu.js +98 -6
- package/routes/notifications.js +39 -11
- package/routes/page.js +4 -1
- package/routes/pageedit.js +4 -1
- package/routes/plugins.js +8 -7
- package/routes/tables.js +11 -0
- package/routes/view.js +12 -3
- package/serve.js +76 -21
- package/tests/admin.test.js +3 -3
- package/tests/auth.test.js +1 -0
- package/tests/viewedit.test.js +2 -0
- package/wrapper.js +26 -193
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/notifications.js
CHANGED
|
@@ -32,14 +32,19 @@ router.use(
|
|
|
32
32
|
})
|
|
33
33
|
);
|
|
34
34
|
|
|
35
|
-
const notificationSettingsForm = () => {
|
|
35
|
+
const notificationSettingsForm = (user) => {
|
|
36
36
|
const fields = [{ name: "notify_email", label: "Email", type: "Bool" }];
|
|
37
|
-
if (getState().getConfig("enable_push_notify", false))
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
if (getState().getConfig("enable_push_notify", false)) {
|
|
38
|
+
const policyByRole = getState()?.getConfig("push_policy_by_role") || {};
|
|
39
|
+
const pushPolicy = policyByRole[user?.role_id || 100] || "Default on";
|
|
40
|
+
if (!["Always", "Never"].includes(pushPolicy)) {
|
|
41
|
+
fields.push({
|
|
42
|
+
name: "notify_push",
|
|
43
|
+
label: "Push",
|
|
44
|
+
type: "Bool",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
43
48
|
|
|
44
49
|
return new Form({
|
|
45
50
|
action: `/notifications/settings`,
|
|
@@ -74,12 +79,23 @@ router.get(
|
|
|
74
79
|
}
|
|
75
80
|
);
|
|
76
81
|
|
|
77
|
-
const form = notificationSettingsForm();
|
|
82
|
+
const form = notificationSettingsForm(req.user);
|
|
78
83
|
const user = await User.findOne({ id: req.user?.id });
|
|
79
84
|
form.values = {
|
|
80
85
|
notify_email: user?._attributes?.notify_email,
|
|
81
|
-
notify_push: user?._attributes?.notify_push,
|
|
82
86
|
};
|
|
87
|
+
|
|
88
|
+
if (getState().getConfig("enable_push_notify", false)) {
|
|
89
|
+
let notifPushAttr = user?._attributes?.notify_push;
|
|
90
|
+
if (notifPushAttr === undefined) {
|
|
91
|
+
const policyByRole = getState()?.getConfig("push_policy_by_role") || {};
|
|
92
|
+
const pushPolicy = policyByRole[user.role_id || 100] || "Default on";
|
|
93
|
+
if (pushPolicy === "Default on") notifPushAttr = true;
|
|
94
|
+
else if (pushPolicy === "Default off") notifPushAttr = false;
|
|
95
|
+
}
|
|
96
|
+
form.values.notify_push = notifPushAttr;
|
|
97
|
+
}
|
|
98
|
+
|
|
83
99
|
const notifyCards = nots.length
|
|
84
100
|
? nots.map((not) => ({
|
|
85
101
|
type: "card",
|
|
@@ -193,11 +209,23 @@ router.post(
|
|
|
193
209
|
loggedIn,
|
|
194
210
|
error_catcher(async (req, res) => {
|
|
195
211
|
const user = await User.findOne({ id: req.user.id });
|
|
196
|
-
const form = notificationSettingsForm();
|
|
212
|
+
const form = notificationSettingsForm(req.user);
|
|
197
213
|
form.validate(req.body || {});
|
|
198
214
|
const _attributes = { ...user._attributes, ...form.values };
|
|
215
|
+
|
|
216
|
+
// apply push enabled policy if needed
|
|
217
|
+
if (getState().getConfig("enable_push_notify", false)) {
|
|
218
|
+
const policyByRole = getState()?.getConfig("push_policy_by_role") || {};
|
|
219
|
+
const pushPolicy = policyByRole[user.role_id || 100] || "Default on";
|
|
220
|
+
if (pushPolicy === "Always") _attributes.notify_push = true;
|
|
221
|
+
else if (pushPolicy === "Never") _attributes.notify_push = false;
|
|
222
|
+
else if (_attributes.notify_push === undefined) {
|
|
223
|
+
_attributes.notify_push = pushPolicy === "Default on";
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
199
227
|
await user.update({ _attributes });
|
|
200
|
-
const pushEnabled =
|
|
228
|
+
const pushEnabled = _attributes.notify_push;
|
|
201
229
|
const allSubs = getState().getConfig("push_notification_subscriptions", {});
|
|
202
230
|
const newSubs = { ...allSubs };
|
|
203
231
|
if (!pushEnabled && newSubs[req.user.id]) {
|
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
|
@@ -174,7 +174,9 @@ const pageBuilderData = async (req, context) => {
|
|
|
174
174
|
const actions = [
|
|
175
175
|
"GoBack",
|
|
176
176
|
...Object.entries(stateActions)
|
|
177
|
-
.filter(
|
|
177
|
+
.filter(
|
|
178
|
+
([k, v]) => !v.requireRow && !v.disableInBuilder && !v.disableIf?.()
|
|
179
|
+
)
|
|
178
180
|
.map(([k, v]) => k),
|
|
179
181
|
];
|
|
180
182
|
const triggers = await Trigger.find({
|
|
@@ -199,6 +201,7 @@ const pageBuilderData = async (req, context) => {
|
|
|
199
201
|
const actionsNotRequiringRow = Trigger.action_options({
|
|
200
202
|
notRequireRow: true,
|
|
201
203
|
apiNeverTriggers: true,
|
|
204
|
+
forBuilder: true,
|
|
202
205
|
builtInLabel: "Page Actions",
|
|
203
206
|
builtIns: ["GoBack"],
|
|
204
207
|
});
|
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
|
@@ -209,7 +209,6 @@ const initMaster = async ({ disableMigrate }, useClusterAdaptor = true) => {
|
|
|
209
209
|
const state = getState();
|
|
210
210
|
if (state) {
|
|
211
211
|
await state.setConfig("joined_log_socket_ids", []);
|
|
212
|
-
await state.setConfig("joined_real_time_socket_ids", []);
|
|
213
212
|
}
|
|
214
213
|
});
|
|
215
214
|
if (useClusterAdaptor) setupPrimary();
|
|
@@ -291,7 +290,8 @@ const onMessageFromWorker =
|
|
|
291
290
|
///ie from saltcorn
|
|
292
291
|
//broadcast
|
|
293
292
|
Object.entries(cluster.workers).forEach(([wpid, w]) => {
|
|
294
|
-
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);
|
|
295
295
|
});
|
|
296
296
|
workerDispatchMsg(msg); //also master
|
|
297
297
|
return true;
|
|
@@ -383,6 +383,13 @@ module.exports =
|
|
|
383
383
|
masterState.listeningTo.add(id);
|
|
384
384
|
}
|
|
385
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
|
+
|
|
386
393
|
if (masterState.listeningTo.size < useNCpus)
|
|
387
394
|
setTimeout(initMasterListeners, 250);
|
|
388
395
|
};
|
|
@@ -421,12 +428,21 @@ module.exports =
|
|
|
421
428
|
|
|
422
429
|
if (forkAnyWorkers) {
|
|
423
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
|
+
};
|
|
424
437
|
|
|
425
438
|
cluster.on("exit", (worker, code, signal) => {
|
|
426
439
|
console.log(`worker ${worker.process.pid} died`);
|
|
427
440
|
addWorker(cluster.fork());
|
|
428
441
|
});
|
|
429
442
|
} else {
|
|
443
|
+
getState().sendMessageToWorkers = (msg) => {
|
|
444
|
+
workerDispatchMsg(msg); //also master
|
|
445
|
+
};
|
|
430
446
|
await nonGreenlockWorkerSetup(appargs, port, host);
|
|
431
447
|
runScheduler({
|
|
432
448
|
port,
|
|
@@ -545,11 +561,26 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
545
561
|
.emit("log_msg", { text: msg, time, level });
|
|
546
562
|
});
|
|
547
563
|
|
|
548
|
-
// Real-time collaboration emitter
|
|
564
|
+
// Real-time collaboration emitter (tied to views)
|
|
549
565
|
getState().setCollabEmitter((tenant, type, data) => {
|
|
550
566
|
io.of("/").to(`_${tenant}_collab_room_`).emit(type, data);
|
|
551
567
|
});
|
|
552
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
|
+
|
|
553
584
|
io.of("/").on("connection", (socket) => {
|
|
554
585
|
socket.on("join_room", ([viewname, room_id]) => {
|
|
555
586
|
const ten = get_tenant_from_req(socket.request) || "public";
|
|
@@ -597,7 +628,7 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
597
628
|
callback({ status: "error", msg: err.message || "unknown error" });
|
|
598
629
|
}
|
|
599
630
|
};
|
|
600
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
631
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
601
632
|
else await f();
|
|
602
633
|
});
|
|
603
634
|
|
|
@@ -614,13 +645,6 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
614
645
|
if (view.min_role < role_id)
|
|
615
646
|
throw new Error("Not authorized to join collaboration room");
|
|
616
647
|
socket.join(`_${tenant}_collab_room_`);
|
|
617
|
-
const socketIds = await getState().getConfig(
|
|
618
|
-
"joined_real_time_socket_ids"
|
|
619
|
-
);
|
|
620
|
-
socketIds.push(socket.id);
|
|
621
|
-
await getState().setConfig("joined_real_time_socket_ids", [
|
|
622
|
-
...socketIds,
|
|
623
|
-
]);
|
|
624
648
|
if (typeof callback === "function") callback({ status: "ok" });
|
|
625
649
|
} catch (err) {
|
|
626
650
|
getState().log(1, `Socket join_collab_room: ${err.stack}`);
|
|
@@ -628,7 +652,30 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
628
652
|
callback({ status: "error", msg: err.message || "unknown error" });
|
|
629
653
|
}
|
|
630
654
|
};
|
|
631
|
-
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);
|
|
632
679
|
else await f();
|
|
633
680
|
});
|
|
634
681
|
|
|
@@ -636,12 +683,20 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
636
683
|
const tenant =
|
|
637
684
|
get_tenant_from_req(socket.request, subdomainOffset) || "public";
|
|
638
685
|
const f = async () => {
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
|
|
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
|
+
}
|
|
642
697
|
};
|
|
643
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
644
|
-
else f();
|
|
698
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
699
|
+
else await f();
|
|
645
700
|
});
|
|
646
701
|
});
|
|
647
702
|
|
|
@@ -689,8 +744,8 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
689
744
|
callback({ status: "error", msg: err.message || "unknown error" });
|
|
690
745
|
}
|
|
691
746
|
};
|
|
692
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
693
|
-
else f();
|
|
747
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
748
|
+
else await f();
|
|
694
749
|
}
|
|
695
750
|
);
|
|
696
751
|
socket.on("write_to_stream", async (data, callback) => {
|
|
@@ -752,8 +807,8 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
752
807
|
}
|
|
753
808
|
});
|
|
754
809
|
};
|
|
755
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
756
|
-
else f();
|
|
810
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
811
|
+
else await f();
|
|
757
812
|
});
|
|
758
813
|
});
|
|
759
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)
|
package/tests/viewedit.test.js
CHANGED
|
@@ -208,6 +208,7 @@ describe("viewedit new List", () => {
|
|
|
208
208
|
.send("contextEnc=" + ctx)
|
|
209
209
|
.send("stepName=Options")
|
|
210
210
|
.send("_row_click_type=Nothing")
|
|
211
|
+
.send("_cell_valign=Middle")
|
|
211
212
|
.set("Cookie", loginCookie)
|
|
212
213
|
.expect(toRedirect("/viewedit"));
|
|
213
214
|
});
|
|
@@ -332,6 +333,7 @@ describe("viewedit new List with one field", () => {
|
|
|
332
333
|
.send("contextEnc=" + ctx)
|
|
333
334
|
.send("stepName=Options")
|
|
334
335
|
.send("_row_click_type=Nothing")
|
|
336
|
+
.send("_cell_valign=Middle")
|
|
335
337
|
.set("Cookie", loginCookie)
|
|
336
338
|
.expect(toRedirect("/viewedit"));
|
|
337
339
|
});
|