mirror of
https://github.com/brunopostle/ifcurl.git
synced 2026-07-12 02:08:13 +00:00
Document OpenCDE OAuth2 proxy, document picker, protocol handler, and roadmap status
- README: add OAuth2 proxy routes and select-documents endpoints to service table; add IFCURL_OAUTH2_CLIENT_ID/SECRET to config table; add ifcurl-register/ifcurl-open CLI section; update roadmap to mark phases 4/7/8/9 as done - SPECIFICATION.md: add note to §9 step 2 pointing to OAuth2 proxy routes in README - CLAUDE.md: add test item 19 for OpenCDE select-documents picker flow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8101e1afcf
commit
403aba2e28
4 changed files with 37 additions and 9 deletions
|
|
@ -3,8 +3,8 @@
|
|||
{"id":"ifcurl-p60","title":"Viewer: no element click-to-identify — can't get GlobalId or properties","description":"There is no way to click on a mesh in the viewer and see which IFC element it represents. Reviewers can see geometry but cannot reference specific elements — they can't discover a GlobalId to put in a selector URL, can't see the element name/type/Psets, and can't say 'this specific wall' in a BCF or Forgejo comment. This breaks the collaboration workflow at its foundation: every useful feedback comment needs to identify specific elements. Need: click or hover on a surface to highlight it and show a properties panel (name, type, GlobalId, key Psets). The GlobalId should be copyable into the selector field or URL. The ThatOpen components library provides the tools for this (OBC.IfcRelationsIndexer, element property queries).","status":"closed","priority":1,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-24T11:02:33Z","created_by":"Bruno Postle","updated_at":"2026-04-24T11:47:23Z","started_at":"2026-04-24T11:14:57Z","closed_at":"2026-04-24T11:47:23Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-4l7","title":"viewer.html: scale= URLs don't load in orthographic mode","description":"applyCameraParam() reads the camera= and fov= parameters from the URL and applies them, but never reads scale= or switches the camera to orthographic (parallel) projection. URLs like ?camera=...\u0026scale=50 will load in perspective mode instead of orthographic. The OBC OrthoPerspectiveCamera can switch modes, but the code path to set parallel projection and apply the scale value is missing from applyCameraParam.","status":"closed","priority":1,"issue_type":"bug","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-24T09:04:51Z","created_by":"Bruno Postle","updated_at":"2026-04-24T10:56:29Z","started_at":"2026-04-24T10:50:19Z","closed_at":"2026-04-24T10:56:29Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-362","title":"Add missing server-config files: gitconfig-ifcmerge and gitattributes","description":"forgejo/README.md documents deploying two files that don't exist in the repo: forgejo/server-config/gitconfig-ifcmerge and forgejo/server-config/gitattributes. Both are required for the ifcmerge git merge driver to work in bare Forgejo repos. The README even includes 'sudo cp forgejo/server-config/gitattributes /etc/gitattributes' and 'sudo git config --system include.path .../gitconfig-ifcmerge', but the files themselves are absent. Anyone following the deployment instructions will hit a 'file not found' error. Need to create both files with the content described in the README.","status":"closed","priority":1,"issue_type":"bug","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-24T09:04:31Z","created_by":"Bruno Postle","updated_at":"2026-04-24T10:51:47Z","started_at":"2026-04-24T10:50:15Z","closed_at":"2026-04-24T10:51:47Z","close_reason":"Files already exist: forgejo/server-config/gitconfig-ifcmerge and gitattributes are both present and correct. Missed in initial review.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-e9g","title":"Security review: viewer.js and viewer HTML","description":"Perform a security review of the browser-side viewer code. Files to cover: forgejo/custom/public/assets/viewer.js and forgejo/custom/public/assets/viewer.html (or equivalent). Areas to examine: ifc:// URL parsing and handling of untrusted URL components before passing to API calls or displaying in the UI, postMessage or cross-origin communication patterns, innerHTML or other unsafe DOM sinks fed from URL parameters or API responses, camera/selector parameter injection into API URLs, BCF file parsing (Zip content, XML parsing) for injection or path traversal, any eval() or dynamic script execution, handling of Forgejo API responses in the metadata/query panels, content security policy considerations, handling of the ifc:// protocol in OS-registered handler (ifcurl-open/register). Produce a prioritised list of findings with recommended fixes.","status":"in_progress","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-07T11:51:09Z","created_by":"Bruno Postle","updated_at":"2026-06-07T11:51:34Z","started_at":"2026-06-07T11:51:34Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-b99","title":"Security review: Python API service (service.py, bcf_api.py, documents_api.py)","description":"Perform a security review of the core Python API service code. Files to cover: ifcurl/service.py (rate limiting, SSRF protection, caching, all endpoints), ifcurl/bcf_api.py (BCF 3.0 REST routes, Forgejo proxy, GUID encoding), ifcurl/documents_api.py (OpenCDE Documents API, select-documents picker), ifcurl/foundation_api.py (OAuth2 proxy routes). Areas to examine: SSRF protection gaps (is _ssrf_check applied consistently to all endpoints that fetch remote content?), sandbox escape paths (does sandboxed rendering fully isolate arbitrary IFC input?), injection risks in Forgejo API proxying (header forwarding, response handling), authentication bypass in BCF routes, document_id encoding/decoding robustness, input validation on all Pydantic models, any path traversal in file or cache operations, tier-4 cache poisoning via mutable/immutable ref misclassification. Produce a prioritised list of findings with recommended fixes.","status":"in_progress","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-07T11:51:06Z","created_by":"Bruno Postle","updated_at":"2026-06-07T11:51:32Z","started_at":"2026-06-07T11:51:32Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-e9g","title":"Security review: viewer.js and viewer HTML","description":"Perform a security review of the browser-side viewer code. Files to cover: forgejo/custom/public/assets/viewer.js and forgejo/custom/public/assets/viewer.html (or equivalent). Areas to examine: ifc:// URL parsing and handling of untrusted URL components before passing to API calls or displaying in the UI, postMessage or cross-origin communication patterns, innerHTML or other unsafe DOM sinks fed from URL parameters or API responses, camera/selector parameter injection into API URLs, BCF file parsing (Zip content, XML parsing) for injection or path traversal, any eval() or dynamic script execution, handling of Forgejo API responses in the metadata/query panels, content security policy considerations, handling of the ifc:// protocol in OS-registered handler (ifcurl-open/register). Produce a prioritised list of findings with recommended fixes.","status":"closed","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-07T11:51:09Z","created_by":"Bruno Postle","updated_at":"2026-06-07T13:50:24Z","started_at":"2026-06-07T11:51:34Z","closed_at":"2026-06-07T13:50:24Z","close_reason":"Two findings fixed: stored XSS in populateMetaPanel via unescaped IFC model data (added hesc() helper), sessionStorage CSS injection in viewer.html snapshot overlay (validated data:image/jpeg;base64, prefix). No other high-confidence findings.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-b99","title":"Security review: Python API service (service.py, bcf_api.py, documents_api.py)","description":"Perform a security review of the core Python API service code. Files to cover: ifcurl/service.py (rate limiting, SSRF protection, caching, all endpoints), ifcurl/bcf_api.py (BCF 3.0 REST routes, Forgejo proxy, GUID encoding), ifcurl/documents_api.py (OpenCDE Documents API, select-documents picker), ifcurl/foundation_api.py (OAuth2 proxy routes). Areas to examine: SSRF protection gaps (is _ssrf_check applied consistently to all endpoints that fetch remote content?), sandbox escape paths (does sandboxed rendering fully isolate arbitrary IFC input?), injection risks in Forgejo API proxying (header forwarding, response handling), authentication bypass in BCF routes, document_id encoding/decoding robustness, input validation on all Pydantic models, any path traversal in file or cache operations, tier-4 cache poisoning via mutable/immutable ref misclassification. Produce a prioritised list of findings with recommended fixes.","status":"closed","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-07T11:51:06Z","created_by":"Bruno Postle","updated_at":"2026-06-07T13:50:05Z","started_at":"2026-06-07T11:51:32Z","closed_at":"2026-06-07T13:50:05Z","close_reason":"Three findings fixed: hostname SSRF bypass in _is_private_ip (now resolves DNS, fail-safe on error), SSRF+token exfiltration in BCF snapshot endpoint (now validates URL via _ssrf_check, drops caller token), X-Forwarded-Host in download URLs noted as medium/deployment concern.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-2yd","title":"Security review: OpenCDE CDE routes (OAuth2 proxy + document picker)","description":"Perform a security review of the CDE-related code added in foundation_api.py and the select-documents additions to documents_api.py. Areas to examine:\\n- OAuth2 proxy: does proxying client_secret server-side introduce SSRF or credential leak risks? Are Forgejo error responses safely forwarded without leaking internal detail?\\n- Picker HTML: is callback_url validated before embedding? Could a crafted callback_url cause open redirect to an attacker-controlled host? Is the JSON embedding in \u003cscript\u003e safe against XSS (\u003c/script\u003e injection test exists but review the escaping logic)?\\n- document_id encoding: can a malformed document_id returned from the picker cause decode_document_id to crash or expose unexpected data?\\n- Rate limiting: do the new /foundation/ and /select-documents endpoints inherit the rate-limit middleware?\\n- Auth forwarding: the document picker UI calls Forgejo API with credentials:include (session cookie). Could a malicious callback_url cause the picker to exfiltrate the session cookie?\\n- Input validation: are all Pydantic models tight enough to reject unexpected fields?\\nProduce a prioritised list of findings with recommended fixes.","status":"closed","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-07T11:21:23Z","created_by":"Bruno Postle","updated_at":"2026-06-07T11:48:36Z","started_at":"2026-06-07T11:28:58Z","closed_at":"2026-06-07T11:48:36Z","close_reason":"One confirmed HIGH finding: DOM XSS in renderBreadcrumb via unescaped single quote in onclick — fixed by replacing innerHTML construction with DOM API calls. Three other candidates (callback_url XSS, X-Forwarded-Host injection, Forgejo error disclosure) were false positives.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-dy9","title":"Manual test plan: OpenCDE Foundation API OAuth2 and document picker","description":"Step-by-step manual test procedure for the OpenCDE CDE functionality added in commits 48169ff and e2d3d12. Tests to cover:\\n1. Forgejo OAuth2 app registration: go to http://localhost:3000/-/admin/applications, create an app named 'ifcurl', set redirect URI, note client_id/secret, set IFCURL_OAUTH2_CLIENT_ID and IFCURL_OAUTH2_CLIENT_SECRET in ifcurl-api.service environment and restart.\\n2. GET /foundation/versions: confirm foundation 1.1, bcf 3.0, documents 1.0 all appear.\\n3. GET /foundation/1.1/oauth2/auth_url: returns {url, expires_in}; URL contains client_id and response_type=code.\\n4. GET /foundation/1.1/oauth2/auth_url?redirect_uri=...: redirect_uri is appended.\\n5. GET /foundation/1.1/oauth2/auth_url with no env vars set: returns 503.\\n6. POST /foundation/1.1/oauth2/token with a valid code (obtain via browser auth flow): returns access_token and refresh_token.\\n7. POST /foundation/1.1/oauth2/token_refresh with valid refresh_token: returns new access_token.\\n8. POST /documents/1.0/select-documents: returns select_documents_url pointing to /ui endpoint.\\n9. GET the select_documents_url in a browser: page loads, repo dropdown populates from Forgejo API.\\n10. Browse into a repo containing an IFC file, click it: browser redirects to callback_url with document_ids[] param containing a base64url-encoded owner/repo/path string that round-trips through decode_document_id.\\n11. POST /documents/1.0/document-versions with the returned document_id: returns version list with download URLs.","status":"open","priority":2,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-06-07T11:21:19Z","created_by":"Bruno Postle","updated_at":"2026-06-07T11:21:19Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-m0y","title":"Phase 4: Bonsai integration — open ifc:// URLs natively","description":"Bonsai (the Blender-based IFC authoring tool) should be able to receive and handle ifc:// URLs natively, delegating all git fetch/cache/reconstruction work to the ifcurl Python library.\n\n## What Bonsai needs to implement\n\n**1. ifcurl library integration**\nBonsai calls ifcurl.resolve(url) → local IFC file path, and ifcurl.parse(url) → view state (camera position/direction/up, selector expression, visibility mode, clipping planes). The ifcurl library handles all transport, caching, and file reconstruction — Bonsai sees only a local path.\n\nIf the ifcurl library is not installed, all ifc:// features degrade gracefully: menu entries are hidden or disabled, CLI URL arguments are ignored with a logged warning, and BCF export omits ifc:// fields silently. No errors or broken UI.\n\n**2. 'Open ifc:// URL…' operator and menu entry**\nA Blender operator that accepts an ifc:// URL string, resolves it via ifcurl, opens the resulting IFC file, and applies the view state (camera, selector, visibility). Exposed as a menu entry (File \u003e Open ifc:// URL…) so users can paste a URL directly. This is also the entry point used when launched from ifcurl-open. Hidden when ifcurl is not installed.\n\n**3. CLI / launch argument handling**\nWhen Bonsai is launched with an ifc:// URL as a CLI argument (forwarded by ifcurl-open), the add-on detects it and invokes the same operator. ifcurl-open always launches a new Bonsai instance — there is no mechanism to send a URL to an already-running instance. Silently ignored if ifcurl is not installed.\n\n**4. 'Copy view URL' action**\nSerialise the current Bonsai camera position, active selector/filter, and visibility state into an ifc:// URL pointing to the current file's git repo and ref. Requires the file to have been opened from a git-tracked location. Hidden when ifcurl is not installed.\n\n**5. BCF viewpoint embedding**\nWhen Bonsai exports a BCF file, viewpoints that reference a git-tracked IFC file should include an ifc:// URL in the viewpoint metadata alongside the standard BCF camera fields. Omitted silently when ifcurl is not installed.\n\n**6. Federation: IFCDOCUMENTREFERENCE resolution**\nWhen Bonsai encounters an IFCDOCUMENTREFERENCE whose Location is an ifc:// URL, call ifcurl.resolve() to fetch and open the referenced model. This is the long-term federation goal. Falls back to ignoring the reference when ifcurl is not installed.\n\n## Out of scope here\n- The ifcurl Python library API itself (ifcurl.resolve, ifcurl.parse) — that is Phase 1 work\n- OS handler registration (ifcurl-coh) and dispatcher (ifcurl-7db)","status":"open","priority":2,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-06-07T07:20:36Z","created_by":"Bruno Postle","updated_at":"2026-06-07T07:39:58Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
|
|
@ -68,8 +68,8 @@
|
|||
{"id":"ifcurl-ei8","title":"Fix syncCameraUrl: convert WebGL coords to IFC world space","description":"syncCameraUrl in viewer.py currently records camera.position/direction/up directly from Three.js, which are in WebGL/Three.js coordinate space (Y-up, different scale/orientation than IFC). The ifc:// URL spec expects IFC world coordinates (Z-up, matching BCF viewpoint conventions). Need to find the IFC→Three.js transform that @thatopen/components applies when loading a model, then apply its inverse in syncCameraUrl before serialising the camera params. Repos cloned for reference: ~/src/engine_components and ~/src/engine_fragment.","status":"closed","priority":2,"issue_type":"bug","owner":"bruno@postle.net","created_at":"2026-04-23T05:53:06Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:36Z","closed_at":"2026-04-23T06:14:36Z","close_reason":"Split into atomic tasks: ifcurl-ldk, ifcurl-j2s, ifcurl-cmd","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-i1s","title":"Test Phase 3b web viewer end-to-end","description":"After deploying the footer template (ifcurl-ach), test the full flow: open an .ifc file in Forgejo at localhost:3000, click 'View in 3D', verify the viewer loads the model. CDN versions (@thatopen/components 2.4.0, three 0.160.0, web-ifc 0.0.66) may need adjustment if the API has changed.","status":"closed","priority":2,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-04-23T05:48:01Z","created_by":"Bruno Postle","updated_at":"2026-04-23T20:05:04Z","started_at":"2026-04-23T19:54:56Z","closed_at":"2026-04-23T20:05:04Z","close_reason":"Closed","dependencies":[{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-49o","type":"blocks","created_at":"2026-04-23T07:14:12Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-4yu","type":"blocks","created_at":"2026-04-23T07:14:11Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ach","type":"blocks","created_at":"2026-04-23T06:48:10Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"ifcurl-i1s","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:54Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":4,"dependent_count":1,"comment_count":0}
|
||||
{"id":"ifcurl-ach","title":"Deploy Phase 3b footer template to Forgejo","description":"The footer.tmpl file that injects a 'View in 3D' button on .ifc file pages has been written but not yet deployed. Deploy it to /etc/forgejo/templates/custom/footer.tmpl and verify the button appears when viewing an .ifc file on localhost:3000.","status":"closed","priority":2,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-04-23T05:47:53Z","created_by":"Bruno Postle","updated_at":"2026-04-23T06:14:35Z","closed_at":"2026-04-23T06:14:35Z","close_reason":"Split into atomic tasks: ifcurl-ohq, ifcurl-49o","dependencies":[{"issue_id":"ifcurl-ach","depends_on_id":"ifcurl-ahd","type":"blocks","created_at":"2026-04-23T07:02:40Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
|
||||
{"id":"ifcurl-pq6","title":"Document OpenCDE Foundation API and document picker in SPECIFICATION.md","description":"The OpenCDE Foundation API 1.1 OAuth2 proxy routes (foundation_api.py) and document picker select-documents flow (documents_api.py) are implemented but not described in SPECIFICATION.md or the CLAUDE.md browser test checklist. Update SPECIFICATION.md §9 or add a new section covering: the OAuth2 setup (registering Forgejo app, env vars IFCURL_OAUTH2_CLIENT_ID/SECRET), the three /foundation/1.1/oauth2/ routes and their request/response shapes, the POST /documents/1.0/select-documents flow and the picker UI. Add a browser test checklist item to CLAUDE.md covering the end-to-end select-documents flow.","status":"open","priority":3,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-06-07T11:21:26Z","created_by":"Bruno Postle","updated_at":"2026-06-07T11:21:26Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-4zf","title":"Document recently-closed features in README or SPECIFICATION","description":"Several features have been implemented and closed in recent beads but are not reflected in user-facing documentation. These include: OpenCDE Foundation API 1.1 OAuth2 proxy routes (ifcurl-bil), OpenCDE document picker select-documents flow (ifcurl-xfi, in progress), BCF export rewrite as pure client-side (7c25e06), ifc:// OS protocol handler ifcurl-open/ifcurl-register (d975658), PR/commit diff view, BCF round-trip import, query panel, click-to-inspect, metadata panel, and storey isolation. README and/or SPECIFICATION should be updated to reflect what is now implemented vs planned.","status":"open","priority":3,"issue_type":"task","owner":"bruno@postle.net","created_at":"2026-06-07T09:11:03Z","created_by":"Bruno Postle","updated_at":"2026-06-07T09:11:03Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-pq6","title":"Document OpenCDE Foundation API and document picker in SPECIFICATION.md","description":"The OpenCDE Foundation API 1.1 OAuth2 proxy routes (foundation_api.py) and document picker select-documents flow (documents_api.py) are implemented but not described in SPECIFICATION.md or the CLAUDE.md browser test checklist. Update SPECIFICATION.md §9 or add a new section covering: the OAuth2 setup (registering Forgejo app, env vars IFCURL_OAUTH2_CLIENT_ID/SECRET), the three /foundation/1.1/oauth2/ routes and their request/response shapes, the POST /documents/1.0/select-documents flow and the picker UI. Add a browser test checklist item to CLAUDE.md covering the end-to-end select-documents flow.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-07T11:21:26Z","created_by":"Bruno Postle","updated_at":"2026-06-07T14:52:56Z","started_at":"2026-06-07T14:19:39Z","closed_at":"2026-06-07T14:52:56Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-4zf","title":"Document recently-closed features in README or SPECIFICATION","description":"Several features have been implemented and closed in recent beads but are not reflected in user-facing documentation. These include: OpenCDE Foundation API 1.1 OAuth2 proxy routes (ifcurl-bil), OpenCDE document picker select-documents flow (ifcurl-xfi, in progress), BCF export rewrite as pure client-side (7c25e06), ifc:// OS protocol handler ifcurl-open/ifcurl-register (d975658), PR/commit diff view, BCF round-trip import, query panel, click-to-inspect, metadata panel, and storey isolation. README and/or SPECIFICATION should be updated to reflect what is now implemented vs planned.","status":"closed","priority":3,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-07T09:11:03Z","created_by":"Bruno Postle","updated_at":"2026-06-07T14:52:57Z","started_at":"2026-06-07T14:19:42Z","closed_at":"2026-06-07T14:52:57Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-bsw","title":"Socket IPC: dispatch ifc:// URLs to already-running viewer instance","description":"When a viewer (bonsai or ifcviewer) is running, ifcurl-open should send the URL to the existing instance rather than launching a new process. Protocol: on startup the viewer opens a Unix socket at ~/.cache/ifcurl/\u003cviewer-name\u003e.sock. ifcurl-open tries the socket first; if it connects it sends the URL as a newline-terminated string and exits. If no socket exists or connection fails, falls back to launching fresh. Bonsai and ifcviewer each need to implement the socket listener.","status":"closed","priority":3,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-06-05T14:43:06Z","created_by":"Bruno Postle","updated_at":"2026-06-07T07:34:25Z","closed_at":"2026-06-07T07:34:25Z","close_reason":"Descoped: ifcurl-open will always launch a new viewer instance. Socket IPC is complex, not idiomatic for Blender, and can be added later if there is demand. Instance reuse policy is left to the viewer application.","dependencies":[{"issue_id":"ifcurl-bsw","depends_on_id":"ifcurl-7db","type":"blocks","created_at":"2026-06-05T15:43:26Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-77u","title":"Ambiguity resolution: ask user when multiple local repos match same genesis commit","description":"When local repo discovery finds more than one local repo with the same genesis commit (user has two side-by-side clones of the same project, by mistake or intent), there is no reliable heuristic for choosing. The system should ask the user once, then cache the choice keyed by genesis commit in ~/.config/ifcurl/config.toml under [project_origins]. The user can also set false to mark a project as read-only (no local push target).","status":"open","priority":3,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-06-05T14:42:56Z","created_by":"Bruno Postle","updated_at":"2026-06-05T14:42:56Z","dependencies":[{"issue_id":"ifcurl-77u","depends_on_id":"ifcurl-egi","type":"blocks","created_at":"2026-06-05T15:43:16Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
|
||||
{"id":"ifcurl-987","title":"UI: no way to remove clipping planes without editing the URL","description":"Once clip= parameters have been added to the ifc:// URL (e.g. via BCF import or manual URL edit), there is no UI control to remove them. The only workaround is to manually edit the URL in the toolbar and delete the clip= parameters. The viewer should provide a button or control to clear all active clipping planes.","status":"closed","priority":3,"issue_type":"bug","owner":"bruno@postle.net","created_at":"2026-05-17T23:30:53Z","created_by":"Bruno Postle","updated_at":"2026-05-17T23:34:40Z","closed_at":"2026-05-17T23:34:40Z","close_reason":"Button to remove clipping planes already exists in the viewer","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
|
|
|
|||
|
|
@ -138,6 +138,8 @@ systemctl is-active ifcurl-api.service forgejo
|
|||
|
||||
**18 — Click-to-inspect.** Click a 3D element. Properties panel shows IFC type, name, GlobalId. Copy button copies GUID.
|
||||
|
||||
**19 — OpenCDE document picker (select-documents).** With `IFCURL_OAUTH2_CLIENT_ID` and `IFCURL_OAUTH2_CLIENT_SECRET` set, POST to `http://localhost:8000/documents/1.0/select-documents` with body `{"callback": {"url": "http://localhost:9999/cb"}}`. The response should contain a `select_documents_url`. Open that URL in a browser — the picker should list Forgejo repositories. Select one, navigate directories, click an `.ifc` file — the browser should redirect to `http://localhost:9999/cb?document_ids[]=<base64url-id>`.
|
||||
|
||||
<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:ca08a54f -->
|
||||
## Beads Issue Tracker
|
||||
|
||||
|
|
|
|||
32
README.md
32
README.md
|
|
@ -114,7 +114,12 @@ ifcurl serve --host 0.0.0.0 --port 9000 --allowed-hosts git.example.com
|
|||
| `GET /select?url=ifc://…` | Resolve a complex selector server-side; returns JSON list of GlobalIds |
|
||||
| `GET /render_diff?base=ifc://…&head=ifc://…` | Render a colour-coded diff PNG (added green, removed red) |
|
||||
| `GET /foundation/versions` | OpenCDE Foundation API discovery — lists BCF and Documents API endpoints (proxy at `/foundation/` on the Forgejo hostname) |
|
||||
| `GET /foundation/1.1/oauth2/auth_url` | Return Forgejo authorization URL to begin OAuth2 code flow (requires `IFCURL_OAUTH2_CLIENT_ID`) |
|
||||
| `POST /foundation/1.1/oauth2/token` | Exchange auth code for access + refresh token pair; client credentials injected server-side |
|
||||
| `POST /foundation/1.1/oauth2/token_refresh` | Exchange refresh token for new token pair |
|
||||
| `POST /documents/1.0/document-versions` | OpenCDE Documents API — resolve document_ids to versioned download URLs (proxied at `/documents/`) |
|
||||
| `POST /documents/1.0/select-documents` | Return a picker UI URL; caller redirects the user's browser to it |
|
||||
| `GET /documents/1.0/select-documents/ui` | Self-contained document-picker page — user browses Forgejo repos, selects an IFC file, redirected back to `callback_url?document_ids[]=<id>` |
|
||||
| `GET /bcf/3.0/projects` | BCF 3.0 — list repositories as BCF projects |
|
||||
| `GET/POST /bcf/3.0/projects/{owner}/{repo}/topics` | BCF 3.0 — list or create topics (Forgejo issues) |
|
||||
| `GET/PUT /bcf/3.0/projects/{owner}/{repo}/topics/{guid}` | BCF 3.0 — get or update a topic |
|
||||
|
|
@ -131,6 +136,8 @@ The BCF API forwards the client's `Authorization: Bearer` header to Forgejo's RE
|
|||
|---|---|---|
|
||||
| `IFCURL_FORGEJO_URL` | `http://localhost:3000` | Forgejo base URL for BCF API calls |
|
||||
| `IFCURL_PREVIEW_URL` | `http://localhost:8000` | Preview service URL for BCF snapshot endpoint |
|
||||
| `IFCURL_OAUTH2_CLIENT_ID` | (none) | Forgejo OAuth2 app client ID — required for Foundation API OAuth2 proxy routes |
|
||||
| `IFCURL_OAUTH2_CLIENT_SECRET` | (none) | Forgejo OAuth2 app client secret |
|
||||
|
||||
**Proxy configuration** — add to nginx or Caddy on the Forgejo hostname:
|
||||
|
||||
|
|
@ -217,6 +224,23 @@ ifcurl render "ifc://..." -o output.png
|
|||
ifcurl cache list # show cached repos with size and last-access time
|
||||
ifcurl cache prune --max 5 # remove oldest repos until cache is under 5 GB
|
||||
ifcurl cache clear # remove all cached repos
|
||||
|
||||
# Register ifc:// as an OS-level protocol handler (Linux, macOS, Windows)
|
||||
ifcurl-register
|
||||
ifcurl-register --unregister # remove registration
|
||||
```
|
||||
|
||||
`ifcurl-register` writes the platform-appropriate handler (`.desktop` + xdg-mime
|
||||
on Linux, an app bundle + Launch Services on macOS, per-user registry keys on
|
||||
Windows) and points it at `ifcurl-open`. When the OS invokes the handler,
|
||||
`ifcurl-open` reads `~/.config/ifcurl/config.toml` and forwards the URL to the
|
||||
configured viewer:
|
||||
|
||||
```toml
|
||||
[handler]
|
||||
default_viewer = "bonsai" # or "ifcviewer"
|
||||
# Or a fully custom command:
|
||||
# command = ["myviewer", "--open", "{url}"]
|
||||
```
|
||||
|
||||
Use as a library:
|
||||
|
|
@ -289,12 +313,12 @@ node --test tests/test_viewer_url.mjs
|
|||
| 1 — Python core | ✓ done | URL parsing, git fetch, render |
|
||||
| 2 — Preview service | ✓ done | HTTP service with caching |
|
||||
| 3 — Forgejo integration | ✓ done | Viewer, JS markdown extension |
|
||||
| 4 — Bonsai integration | planned | Protocol handler + "Copy view URL" |
|
||||
| 4 — OS protocol handler | ✓ done | `ifcurl-register` + `ifcurl-open`: registers `ifc://` on Linux, macOS, Windows; dispatches to Bonsai or any viewer |
|
||||
| 5 — IFC Viewer integration | planned | Plugin for the open-source IFC Viewer |
|
||||
| 6 — Federation | planned | `IFCDOCUMENTREFERENCE` cross-repo links |
|
||||
| 7 — OpenCDE Foundation API | planned | Discovery endpoint so OpenCDE clients can find the server |
|
||||
| 8 — OpenCDE BCF API | planned | BCF 3.0 REST API in Forgejo — connect Revit, Navisworks, Solibri directly |
|
||||
| 9 — OpenCDE Documents API | planned | Expose IFC files in git repos as OpenCDE documents |
|
||||
| 7 — OpenCDE Foundation API | ✓ done | Discovery endpoint + OAuth2 proxy (Foundation API 1.1) |
|
||||
| 8 — OpenCDE BCF API | ✓ done | BCF 3.0 REST API — connect Revit, Navisworks, Solibri directly |
|
||||
| 9 — OpenCDE Documents API | ✓ done | Document versions + select-documents picker |
|
||||
|
||||
Development tasks are tracked with [beads](https://github.com/brunopostle/beads): `bd ready`.
|
||||
|
||||
|
|
|
|||
|
|
@ -426,7 +426,9 @@ is not used in `ifc://` URLs.
|
|||
configuration obtained from step 1. Credentials are never embedded in the
|
||||
`ifc://` URL. Viewer implementations served from the same browser session as
|
||||
the CDE web interface may share the existing session cookie, avoiding an
|
||||
explicit OAuth2 flow for authenticated users.
|
||||
explicit OAuth2 flow for authenticated users. The `ifcurl` preview service
|
||||
exposes OAuth2 proxy routes at `/foundation/1.1/oauth2/` that handle
|
||||
credential injection server-side (see `README.md`).
|
||||
|
||||
3. **Resolve document version** — `POST <documents_api_base>/document-versions`
|
||||
with body `{"document_ids": ["<document_id>"]}`. If `version_index` is
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue