Conversation
…er-side validation - Use current_user.is_organization_member() instead of inline comprehension - Add explicit comment on admin bypass rationale - Clarify is_authenticated guard intent in docstring - Add server-side org_id membership check in process_form create path - Fix import order in schema.py (mosp.views after mosp.models) - Add tests: 404, admin bypass, POST protection (6 tests total)
GET /schema/delete/<id> now shows a warning page with the schema name and a count of objects that would be cascade-deleted; POST performs the actual delete and redirects to the schemas list. Both routes are protected by @login_required and @check_schema_edit_permission. A SimpleForm is added to forms.py for CSRF protection on the confirmation form. Tests cover owner GET (200), non-owner GET/POST (403), and successful POST delete (302 + DB removal).
…only UI, BS5 spacing
- Add forked_from_id self-referential FK to Schema model - Alembic migration: c3f2a1b4e5d6 - POST /schema/fork/<id> route: copy schema into user's org, set provenance - Fork modal in schema.html with org selector (Bootstrap 5) - Provenance badge linking back to source schema - Proper 403 error page (replaces redirect-to-login behavior) - 3 new tests: fork creates copy, unauth redirects, wrong org rejects
Python (pip-audit): - flask 3.0.2 → 3.1.3 (CVE-2026-27205) - werkzeug 3.0.1 → 3.1.8 (CVE-2024-34069, CVE-2024-49766/67, CVE-2025-66221, CVE-2026-21860/27199) - flask-cors 3.0.10 → 6.0.2 (PYSEC-2024-71, CVE-2024-1681/6844/6866/6839) - requests 2.31.0 → 2.33.1 (CVE-2024-35195, CVE-2024-47081, CVE-2026-25645) - certifi 2024.2.2 → 2026.2.25 (PYSEC-2024-230) - idna 3.6 → 3.11 (PYSEC-2024-60) JS (npm update — no vulnerabilities, minor bumps): - @fortawesome/fontawesome-free 6.6.0 → 6.7.2 - @json-editor/json-editor 2.15.1 → 2.16.0 - bootstrap 5.3.3 → 5.3.8 - chart.js 4.4.3 → 4.5.1 - codemirror 6.0.1 → 6.0.2 - datatables.net-bs4 2.1.3 → 2.3.7 - papaparse 5.4.1 → 5.5.3
- docker-compose.yml: remove empty SECRET_KEY/SECURITY_PASSWORD_SALT placeholders that caused docker-compose up to crash; replace with comments only - mosp/models/schema.py: wrap forked_from_id column and relationship definitions to respect 100-char line limit (flake8 E501) - mosp/templates/errors/403.html: replace Bootstrap 3 'well' class with Bootstrap 5 'alert alert-danger' - mosp/templates/schema.html: apply same org-membership guard to edit button as already applied to delete button (cosmetic hardening) - tests/test_schema.py: add test verifying forged org_id is rejected on schema creation; correct assertion to 302 since WTForms choice validation fires first - .gitignore: exclude instance/test.py and uv.lock
Replace datetime.utcnow() (deprecated in Python 3.12) with datetime.now(timezone.utc).replace(tzinfo=None) across all models and views. Replace print(e) debug calls in api/v2 with proper logger.error() calls using exc_info=True.
Replace data-toggle/data-dismiss/data-target with data-bs-* equivalents across all templates. Replace Bootstrap 4 .close buttons with Bootstrap 5 .btn-close. Downgrade codemirror from v6 (ES-module-only) to v5.65.x which matches the lib/codemirror.js path used in edit_schema.html.
Build a self-hosted IIFE bundle (mosp/static/js/codemirror-bundle.js) from codemirror@6 + @codemirror/lang-json using esbuild. The bundle is rebuilt via `npm run build` or automatically on `npm install`. Update edit_schema.html to use the CM6 EditorView API. Replace the deprecated CodeMirror.fromTextArea() (v5) with EditorView + basicSetup and JSON language support. The textarea value is synced back on submit.
Bootstrap 5 requires @popperjs/core v2. popper.js v1 does not expose createPopper(), causing all dropdowns to fail with a TypeError.
Add data-bs-display="static" to navbar dropdown toggles to prevent Popper from positioning menus outside the viewport. Rename dropdown-menu-right to dropdown-menu-end (Bootstrap 5 rename).
In edit_schema, warn that the user must join/create an org before creating a schema, with a link to the organizations list. In admin edit_user, replace the broken bootstrap-select with a native Bootstrap 5 form-select, and show a warning with a link to create an org when no organizations exist yet.
Remove bootstrap-select (Bootstrap 4 only) entirely. Replace all .selectpicker instances with .form-select across edit_object, edit_collection, view_object, schema, admin/edit_organization templates. Add Ctrl/Cmd hint on multi-selects. Remove unused bootstrap-select CSS/JS from layout.html and uninstall the package.
Replace btn-default with btn-secondary/btn-primary. Consolidate all event listeners inside DOMContentLoaded. Fix implicit global variable (inputContent). Replace jQuery option manipulation with native select.options.length = 0 and new Option(). Use insertAdjacentHTML instead of innerHTML += for badge appending.
Global replacements: - btn-default → btn-secondary - text-right/left → text-end/start - sr-only → visually-hidden - float-right/left → float-end/start - font-weight-* → fw-* - badge-pill → rounded-pill, badge-primary → badge bg-primary - form-row → row, form-group → mb-3 - text-justify removed (no BS5 equivalent) Per-file structural fixes: - about.html, index.html: jumbotron → p-5 bg-light rounded - errors/404,500,503.html: .well → alert alert-warning/danger - edit_user.html: navbar-form/input-group-prepend/append removed; restructured API key input-group for Bootstrap 5 - edit_json.html: toast header mr-auto → me-auto, close → btn-close - layout.html: navbar ul mr-auto → me-auto
- Replace all inline style="color:red" form errors with Bootstrap text-danger divs
- Add proper <label for="..."> elements to account_recovery, signup, set_password forms
- Replace deprecated align= HTML attributes with Bootstrap float-start/text-center classes
- Fix bSortable -> orderable in DataTables config across 5 templates
- Remove spurious extra } from {% extends %} tags in help.html, terms.html, organization.html
- Fix onclick confirm() placed on icon children instead of parent anchor links
- Fix incorrect "Delete the object" title on collection delete button
- Fix label for= mismatch in edit_collection.html (description -> inputObject)
- Replace inline style="color:blue" icon with text-primary utility class
- Replace deprecated fa-remove icon with fa-trash in admin organizations
- Fix double badge class (badge badge bg-*) in user.html and schemas.html
- Standardize responsive table wrapper in view_diff.html
- Fix schema.html search input missing form-control class
- Add empty-state messages to all list/table views (no collections, objects, schemas, organizations)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2febfcacec
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| op.create_foreign_key( | ||
| "fk_schema_forked_from_id", | ||
| "schema", | ||
| "schema", | ||
| ["forked_from_id"], | ||
| ["id"], |
There was a problem hiding this comment.
Allow deleting schemas that have been forked
The new self-referential foreign key on schema.forked_from_id is created without an ondelete action, so PostgreSQL keeps the default NO ACTION behavior. After this migration, deleting an original schema that has at least one fork will raise an integrity error and make the new /schema/delete/<id> flow fail with a 500 at commit time. This blocks a core operation for any schema that has been forked.
Useful? React with 👍 / 👎.
| base_name = source.name + " (fork)" | ||
| name = base_name |
There was a problem hiding this comment.
Bound fork names to the schema name column size
Fork names are generated by appending " (fork)" (and optionally a numeric suffix) to the source name, but Schema.name is limited to 100 characters. Forking any schema with a long valid name (e.g. 94+ chars) will produce an overlong value and trigger a DB error on db.session.commit(), returning a server error instead of creating the fork.
Useful? React with 👍 / 👎.
What does it do?
This PR delivers the v0.18.0 release of MOSP, combining security hardening, two long-standing feature requests, a frontend modernization, and general UX polish.
Security fixes
SECRET_KEYandSECURITY_PASSWORD_SALTfrom environment variables instead of hardcoded values in config files (closes Recommendation to remove a default secret key #79)org_idserver-side validationNew features
forked_fromprovenance reference displayed on the schema page (closes Copy a schema from an organization to an other #3)Frontend
data-bs-*attributes, spacing utilities, removedbootstrap-select, replacedpopper.jsv1 with@popperjs/corev2)style="color:red"form errors with Bootstraptext-dangerutility classes<label for="…">elements to recovery, signup, and set-password formsbSortable→orderablein DataTables config (deprecated API)onclickon<i>icon children instead of parent<a>links (confirm dialogs were non-functional)badgeclasses, deprecatedalign=HTML attributes, and spurious}in three{% extends %}tagsOther
datetime.utcnow()with timezone-aware equivalent across all modelsprint(e)debug statement withlogger.error()inobjectbp.pypostgresql://scheme in production config sample (required by SQLAlchemy 2.x)Questions
Schema.forked_from_id(nullable FK). A migration is included.Release Type: