@saltcorn/server 1.3.1-beta.1 → 1.3.1-beta.11
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 +68 -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 +4 -2
- 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 +94 -39
- package/public/saltcorn.css +12 -0
- package/public/saltcorn.js +44 -6
- package/routes/actions.js +14 -0
- package/routes/admin.js +71 -18
- 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 +97 -43
- package/tests/admin.test.js +3 -3
- package/tests/auth.test.js +1 -0
- package/tests/viewedit.test.js +2 -0
- package/wrapper.js +23 -191
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
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
init_multi_tenant,
|
|
15
15
|
restart_tenant,
|
|
16
16
|
add_tenant,
|
|
17
|
+
get_other_domain_tenant,
|
|
17
18
|
} = require("@saltcorn/data/db/state");
|
|
18
19
|
const { create_tenant } = require("@saltcorn/admin-models/models/tenant");
|
|
19
20
|
|
|
@@ -79,17 +80,6 @@ const ensureJwtSecret = () => {
|
|
|
79
80
|
}
|
|
80
81
|
};
|
|
81
82
|
|
|
82
|
-
/**
|
|
83
|
-
* Ensure the engines cache is up to date with the current sc version
|
|
84
|
-
*/
|
|
85
|
-
const ensureEnginesCache = async () => {
|
|
86
|
-
const cacheScVersion = await getConfig("engines_cache_sc_version", "");
|
|
87
|
-
if (!cacheScVersion || cacheScVersion !== getState().scVersion) {
|
|
88
|
-
await setConfig("engines_cache", {});
|
|
89
|
-
await setConfig("engines_cache_sc_version", getState().scVersion);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
83
|
/**
|
|
94
84
|
* validate all plugins folders and remove invalid entries
|
|
95
85
|
* A folder is invalid when it has dependencies but not node_modules directory
|
|
@@ -205,12 +195,6 @@ const initMaster = async ({ disableMigrate }, useClusterAdaptor = true) => {
|
|
|
205
195
|
const tenants = await getAllTenants();
|
|
206
196
|
await init_multi_tenant(loadAllPlugins, disableMigrate, tenants);
|
|
207
197
|
}
|
|
208
|
-
eachTenant(async () => {
|
|
209
|
-
const state = getState();
|
|
210
|
-
if (state) {
|
|
211
|
-
await state.setConfig("joined_log_socket_ids", []);
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
198
|
if (useClusterAdaptor) setupPrimary();
|
|
215
199
|
};
|
|
216
200
|
|
|
@@ -234,7 +218,11 @@ const workerDispatchMsg = ({ tenant, ...msg }) => {
|
|
|
234
218
|
console.error("no State for tenant", tenant);
|
|
235
219
|
return;
|
|
236
220
|
}
|
|
237
|
-
if (msg.refresh)
|
|
221
|
+
if (msg.refresh) {
|
|
222
|
+
if (msg.refresh === "ephemeral_config")
|
|
223
|
+
getState().refresh_ephemeral_config(msg.key, msg.value);
|
|
224
|
+
else getState()[`refresh_${msg.refresh}`](true);
|
|
225
|
+
}
|
|
238
226
|
if (msg.createTenant) {
|
|
239
227
|
const tenant_template = getState().getConfig("tenant_template");
|
|
240
228
|
add_tenant(msg.createTenant);
|
|
@@ -290,7 +278,8 @@ const onMessageFromWorker =
|
|
|
290
278
|
///ie from saltcorn
|
|
291
279
|
//broadcast
|
|
292
280
|
Object.entries(cluster.workers).forEach(([wpid, w]) => {
|
|
293
|
-
if
|
|
281
|
+
//if it is plugin refresh, we need sender to get it as wll
|
|
282
|
+
if (wpid !== pid || msg?.refresh_plugin_cfg) w.send(msg);
|
|
294
283
|
});
|
|
295
284
|
workerDispatchMsg(msg); //also master
|
|
296
285
|
return true;
|
|
@@ -322,7 +311,6 @@ module.exports =
|
|
|
322
311
|
} = {}) => {
|
|
323
312
|
if (cluster.isMaster) {
|
|
324
313
|
ensureJwtSecret();
|
|
325
|
-
await ensureEnginesCache();
|
|
326
314
|
await ensurePluginsFolder();
|
|
327
315
|
await ensureNotificationSubscriptions();
|
|
328
316
|
}
|
|
@@ -382,6 +370,13 @@ module.exports =
|
|
|
382
370
|
masterState.listeningTo.add(id);
|
|
383
371
|
}
|
|
384
372
|
});
|
|
373
|
+
getState().sendMessageToWorkers = (msg) => {
|
|
374
|
+
Object.entries(cluster.workers).forEach(([wpid, w]) => {
|
|
375
|
+
w.send(msg);
|
|
376
|
+
});
|
|
377
|
+
workerDispatchMsg(msg); //also master
|
|
378
|
+
};
|
|
379
|
+
|
|
385
380
|
if (masterState.listeningTo.size < useNCpus)
|
|
386
381
|
setTimeout(initMasterListeners, 250);
|
|
387
382
|
};
|
|
@@ -420,12 +415,21 @@ module.exports =
|
|
|
420
415
|
|
|
421
416
|
if (forkAnyWorkers) {
|
|
422
417
|
for (let i = 0; i < useNCpus; i++) addWorker(cluster.fork());
|
|
418
|
+
getState().sendMessageToWorkers = (msg) => {
|
|
419
|
+
Object.entries(cluster.workers).forEach(([wpid, w]) => {
|
|
420
|
+
w.send(msg);
|
|
421
|
+
});
|
|
422
|
+
workerDispatchMsg(msg); //also master
|
|
423
|
+
};
|
|
423
424
|
|
|
424
425
|
cluster.on("exit", (worker, code, signal) => {
|
|
425
426
|
console.log(`worker ${worker.process.pid} died`);
|
|
426
427
|
addWorker(cluster.fork());
|
|
427
428
|
});
|
|
428
429
|
} else {
|
|
430
|
+
getState().sendMessageToWorkers = (msg) => {
|
|
431
|
+
workerDispatchMsg(msg); //also master
|
|
432
|
+
};
|
|
429
433
|
await nonGreenlockWorkerSetup(appargs, port, host);
|
|
430
434
|
runScheduler({
|
|
431
435
|
port,
|
|
@@ -508,6 +512,16 @@ const nonGreenlockWorkerSetup = async (appargs, port, host) => {
|
|
|
508
512
|
getState().processSend("Start");
|
|
509
513
|
};
|
|
510
514
|
|
|
515
|
+
const tenantFromSocket = (socket, hostPartOffset) => {
|
|
516
|
+
const header = socket.request.headers.host;
|
|
517
|
+
const hostOnly = header?.split(":")[0];
|
|
518
|
+
if (hostOnly) {
|
|
519
|
+
const tenant = get_other_domain_tenant(hostOnly);
|
|
520
|
+
if (tenant) return tenant;
|
|
521
|
+
}
|
|
522
|
+
return get_tenant_from_req(socket.request, hostPartOffset);
|
|
523
|
+
};
|
|
524
|
+
|
|
511
525
|
/**
|
|
512
526
|
*
|
|
513
527
|
* @param {...*} servers
|
|
@@ -544,14 +558,29 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
544
558
|
.emit("log_msg", { text: msg, time, level });
|
|
545
559
|
});
|
|
546
560
|
|
|
547
|
-
// Real-time collaboration emitter
|
|
561
|
+
// Real-time collaboration emitter (tied to views)
|
|
548
562
|
getState().setCollabEmitter((tenant, type, data) => {
|
|
549
563
|
io.of("/").to(`_${tenant}_collab_room_`).emit(type, data);
|
|
550
564
|
});
|
|
551
565
|
|
|
566
|
+
// dynamic updates emitter (for run_js_actions)
|
|
567
|
+
getState().setDynamicUpdateEmitter((tenant, data, userIds) => {
|
|
568
|
+
if (userIds) {
|
|
569
|
+
for (const userId of userIds) {
|
|
570
|
+
io.of("/")
|
|
571
|
+
.to(`_${tenant}:${userId}_dynamic_update_room`)
|
|
572
|
+
.emit("dynamic_update", data);
|
|
573
|
+
}
|
|
574
|
+
} else {
|
|
575
|
+
io.of("/")
|
|
576
|
+
.to(`_${tenant}_dynamic_update_room`)
|
|
577
|
+
.emit("dynamic_update", data);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
|
|
552
581
|
io.of("/").on("connection", (socket) => {
|
|
553
582
|
socket.on("join_room", ([viewname, room_id]) => {
|
|
554
|
-
const ten =
|
|
583
|
+
const ten = tenantFromSocket(socket, subdomainOffset) || "public";
|
|
555
584
|
const f = () => {
|
|
556
585
|
try {
|
|
557
586
|
const view = View.findOne({ name: viewname });
|
|
@@ -571,8 +600,7 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
571
600
|
});
|
|
572
601
|
|
|
573
602
|
socket.on("join_log_room", async (callback) => {
|
|
574
|
-
const tenant =
|
|
575
|
-
get_tenant_from_req(socket.request, subdomainOffset) || "public";
|
|
603
|
+
const tenant = tenantFromSocket(socket, subdomainOffset) || "public";
|
|
576
604
|
const f = async () => {
|
|
577
605
|
try {
|
|
578
606
|
const user = socket.request.user;
|
|
@@ -596,14 +624,13 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
596
624
|
callback({ status: "error", msg: err.message || "unknown error" });
|
|
597
625
|
}
|
|
598
626
|
};
|
|
599
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
627
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
600
628
|
else await f();
|
|
601
629
|
});
|
|
602
630
|
|
|
603
631
|
// or join the room more generally and later register views ??
|
|
604
632
|
socket.on("join_collab_room", async (viewname, callback) => {
|
|
605
|
-
const tenant =
|
|
606
|
-
get_tenant_from_req(socket.request, subdomainOffset) || "public";
|
|
633
|
+
const tenant = tenantFromSocket(socket, subdomainOffset) || "public";
|
|
607
634
|
const f = async () => {
|
|
608
635
|
try {
|
|
609
636
|
const view = View.findOne({ name: viewname });
|
|
@@ -620,20 +647,49 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
620
647
|
callback({ status: "error", msg: err.message || "unknown error" });
|
|
621
648
|
}
|
|
622
649
|
};
|
|
623
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
650
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
651
|
+
else await f();
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
// join_dynamic_update_room for events emitted from run_js_actions
|
|
655
|
+
socket.on("join_dynamic_update_room", async (callback) => {
|
|
656
|
+
const tenant = tenantFromSocket(socket, subdomainOffset) || "public";
|
|
657
|
+
const f = async () => {
|
|
658
|
+
try {
|
|
659
|
+
const enabled = getState().getConfig("enable_dynamic_updates", true);
|
|
660
|
+
if (!enabled) throw new Error("Dynamic updates are not enabled");
|
|
661
|
+
const user = socket.request.user;
|
|
662
|
+
if (!user) throw new Error("Not authorized");
|
|
663
|
+
socket.join(`_${tenant}_dynamic_update_room`);
|
|
664
|
+
socket.join(`_${tenant}:${user.id}_dynamic_update_room`);
|
|
665
|
+
if (typeof callback === "function") callback({ status: "ok" });
|
|
666
|
+
} catch (err) {
|
|
667
|
+
getState().log(1, `Socket join_dynamic_update_room: ${err.stack}`);
|
|
668
|
+
if (typeof callback === "function")
|
|
669
|
+
callback({ status: "error", msg: err.message || "unknown error" });
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
624
673
|
else await f();
|
|
625
674
|
});
|
|
626
675
|
|
|
627
676
|
socket.on("disconnect", async () => {
|
|
628
|
-
const tenant =
|
|
629
|
-
get_tenant_from_req(socket.request, subdomainOffset) || "public";
|
|
677
|
+
const tenant = tenantFromSocket(socket, subdomainOffset) || "public";
|
|
630
678
|
const f = async () => {
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
|
|
679
|
+
const state = getState();
|
|
680
|
+
if (state) {
|
|
681
|
+
const socketIds = state.getConfig("joined_log_socket_ids");
|
|
682
|
+
const newSocketIds = socketIds.filter((id) => id !== socket.id);
|
|
683
|
+
await state.setConfig("joined_log_socket_ids", newSocketIds);
|
|
684
|
+
} else {
|
|
685
|
+
console.error("No state found in socket disconnect");
|
|
686
|
+
console.error("The current tenantSchema is:", db.getTenantSchema());
|
|
687
|
+
console.error("The current tenant from request is:", tenant);
|
|
688
|
+
console.error("node version:", process.version);
|
|
689
|
+
}
|
|
634
690
|
};
|
|
635
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
636
|
-
else f();
|
|
691
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
692
|
+
else await f();
|
|
637
693
|
});
|
|
638
694
|
});
|
|
639
695
|
|
|
@@ -643,8 +699,7 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
643
699
|
socket.on(
|
|
644
700
|
"open_data_stream",
|
|
645
701
|
async ([viewName, id, fieldName, fieldView, targetOpts], callback) => {
|
|
646
|
-
const tenant =
|
|
647
|
-
get_tenant_from_req(socket.request, subdomainOffset) || "public";
|
|
702
|
+
const tenant = tenantFromSocket(socket, subdomainOffset) || "public";
|
|
648
703
|
const f = async () => {
|
|
649
704
|
try {
|
|
650
705
|
const user = socket.request.user;
|
|
@@ -681,8 +736,8 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
681
736
|
callback({ status: "error", msg: err.message || "unknown error" });
|
|
682
737
|
}
|
|
683
738
|
};
|
|
684
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
685
|
-
else f();
|
|
739
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
740
|
+
else await f();
|
|
686
741
|
}
|
|
687
742
|
);
|
|
688
743
|
socket.on("write_to_stream", async (data, callback) => {
|
|
@@ -723,8 +778,7 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
723
778
|
});
|
|
724
779
|
|
|
725
780
|
socket.on("disconnect", async () => {
|
|
726
|
-
const tenant =
|
|
727
|
-
get_tenant_from_req(socket.request, subdomainOffset) || "public";
|
|
781
|
+
const tenant = tenantFromSocket(socket, subdomainOffset) || "public";
|
|
728
782
|
const f = async () => {
|
|
729
783
|
if (dataStream)
|
|
730
784
|
dataStream.close((err) => {
|
|
@@ -744,8 +798,8 @@ const setupSocket = (subdomainOffset, pruneSessionInterval, ...servers) => {
|
|
|
744
798
|
}
|
|
745
799
|
});
|
|
746
800
|
};
|
|
747
|
-
if (tenant && tenant !== "public") db.runWithTenant(tenant, f);
|
|
748
|
-
else f();
|
|
801
|
+
if (tenant && tenant !== "public") await db.runWithTenant(tenant, f);
|
|
802
|
+
else await f();
|
|
749
803
|
});
|
|
750
804
|
});
|
|
751
805
|
};
|
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
|
});
|