diff --git a/composer.json b/composer.json
index 378897b..d046761 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "fleetbase/solid-api",
- "version": "0.0.5",
+ "version": "0.0.6",
"description": "Solid Protocol Extension to Store and Share Data with Fleetbase",
"keywords": [
"fleetbase-extension",
diff --git a/extension.json b/extension.json
index 702d6d1..94ba457 100644
--- a/extension.json
+++ b/extension.json
@@ -1,6 +1,6 @@
{
"name": "Solid",
- "version": "0.0.5",
+ "version": "0.0.6",
"description": "Solid Protocol Extension to Store and Share Data with Fleetbase",
"repository": "https://github.com/fleetbase/solid",
"license": "AGPL-3.0-or-later",
diff --git a/package.json b/package.json
index d229147..4125c7d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@fleetbase/solid-engine",
- "version": "0.0.5",
+ "version": "0.0.6",
"description": "Solid Protocol Extension to Store and Share Data with Fleetbase",
"fleetbase": {
"route": "solid-protocol"
@@ -46,7 +46,7 @@
"dependencies": {
"@babel/core": "^7.23.2",
"@fleetbase/ember-core": "^0.3.9",
- "@fleetbase/ember-ui": "^0.3.15",
+ "@fleetbase/ember-ui": "^0.3.16",
"@fleetbase/fleetops-data": "^0.1.24",
"@fortawesome/ember-fontawesome": "^2.0.0",
"@fortawesome/fontawesome-svg-core": "6.4.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 76e932b..89b8f68 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,8 +15,8 @@ importers:
specifier: ^0.3.9
version: 0.3.9(@ember/string@3.1.1)(@ember/test-helpers@3.3.1(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(webpack@5.104.1))(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)))(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(eslint@8.57.1)(webpack@5.104.1)
'@fleetbase/ember-ui':
- specifier: ^0.3.15
- version: 0.3.15(@ember/test-helpers@3.3.1(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(webpack@5.104.1))(@glimmer/component@1.1.2(@babel/core@7.28.5))(@glimmer/tracking@1.1.2)(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)))(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(postcss@8.5.6)(rollup@2.79.2)(tracked-built-ins@3.4.0(@babel/core@7.28.5))(webpack@5.104.1)
+ specifier: ^0.3.16
+ version: 0.3.16(@ember/test-helpers@3.3.1(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(webpack@5.104.1))(@glimmer/component@1.1.2(@babel/core@7.28.5))(@glimmer/tracking@1.1.2)(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)))(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(postcss@8.5.6)(rollup@2.79.2)(tracked-built-ins@3.4.0(@babel/core@7.28.5))(webpack@5.104.1)
'@fleetbase/fleetops-data':
specifier: ^0.1.24
version: 0.1.24(@ember/string@3.1.1)(@ember/test-helpers@3.3.1(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(webpack@5.104.1))(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)))(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(eslint@8.57.1)(webpack@5.104.1)
@@ -1225,6 +1225,15 @@ packages:
'@glint/template':
optional: true
+ '@embroider/macros@1.19.6':
+ resolution: {integrity: sha512-yPf8lD/gRZmcxms66CCKuZuvWMJ0g/hdCE6P8FZsyewR3So6pxgdgOFp0zk2w5d34jS1ejBtxLNREZbBTELpzw==}
+ engines: {node: 12.* || 14.* || >= 16}
+ peerDependencies:
+ '@glint/template': ^1.0.0
+ peerDependenciesMeta:
+ '@glint/template':
+ optional: true
+
'@embroider/reverse-exports@0.2.0':
resolution: {integrity: sha512-WFsw8nQpHZiWGEDYpa/A79KEFfTisqteXbY+jg9eZiww1r1G+LZvsmdszDp86TkotUSCqrMbK/ewn0jR1CJmqg==}
engines: {node: 12.* || 14.* || >= 16}
@@ -1241,6 +1250,10 @@ packages:
resolution: {integrity: sha512-d7RQwDwqqHo7YvjE9t1rtIrCCYtbSoO0uRq2ikVhRh4hGS5OojZNu2ZtS0Wqrg+V72CRtMFr/hibTvHNsRM2Lg==}
engines: {node: 12.* || 14.* || >= 16}
+ '@embroider/shared-internals@3.0.2':
+ resolution: {integrity: sha512-/SusdG+zgosc3t+9sPFVKSFOYyiSgLfXOT6lYNWoG1YtnhWDxlK4S8leZ0jhcVjemdaHln5rTyxCnq8oFLxqpQ==}
+ engines: {node: 12.* || 14.* || >= 16}
+
'@embroider/test-setup@3.0.3':
resolution: {integrity: sha512-3K5KSyTdnxAkZQill6+TdC/XTRr6226LNwZMsrhRbBM0FFZXw2D8qmJSHPvZLheQx3A1jnF9t1lyrAzrKlg6Yw==}
engines: {node: 12.* || 14.* || >= 16}
@@ -1297,8 +1310,8 @@ packages:
resolution: {integrity: sha512-CxMEyNGhSk0u8SkI6GZiKY2W/246PyBpY6clZahoxtyokL76kWx2KjEk4iXqKdhKKU5a5OKlS8Kw9wb0peZZzw==}
engines: {node: '>= 18'}
- '@fleetbase/ember-ui@0.3.15':
- resolution: {integrity: sha512-eKzaUyTUa6Fp8seRS0dB/6+tf///YVMx8MvuJPQoKBupxmQ7i+D6iehu6KBrbDRfoHVWRL6/44WmoTZoDzDQRA==}
+ '@fleetbase/ember-ui@0.3.16':
+ resolution: {integrity: sha512-3JewcvB86pUEcMN+aOmPR6hA6OaFRbxDuHjRMguP16zQOd31++Qr0rOviTaNyih2SIwoJCjCTc3FS1Umanko3w==}
engines: {node: '>= 18'}
'@fleetbase/fleetops-data@0.1.24':
@@ -1380,18 +1393,18 @@ packages:
resolution: {integrity: sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ==}
engines: {node: '>=6'}
- '@fullcalendar/core@6.1.19':
- resolution: {integrity: sha512-z0aVlO5e4Wah6p6mouM0UEqtRf1MZZPt4mwzEyU6kusaNL+dlWQgAasF2cK23hwT4cmxkEmr4inULXgpyeExdQ==}
+ '@fullcalendar/core@6.1.20':
+ resolution: {integrity: sha512-1cukXLlePFiJ8YKXn/4tMKsy0etxYLCkXk8nUCFi11nRONF2Ba2CD5b21/ovtOO2tL6afTJfwmc1ed3HG7eB1g==}
- '@fullcalendar/daygrid@6.1.19':
- resolution: {integrity: sha512-IAAfnMICnVWPjpT4zi87i3FEw0xxSza0avqY/HedKEz+l5MTBYvCDPOWDATpzXoLut3aACsjktIyw9thvIcRYQ==}
+ '@fullcalendar/daygrid@6.1.20':
+ resolution: {integrity: sha512-AO9vqhkLP77EesmJzuU+IGXgxNulsA8mgQHynclJ8U70vSwAVnbcLG9qftiTAFSlZjiY/NvhE7sflve6cJelyQ==}
peerDependencies:
- '@fullcalendar/core': ~6.1.19
+ '@fullcalendar/core': ~6.1.20
- '@fullcalendar/interaction@6.1.19':
- resolution: {integrity: sha512-GOciy79xe8JMVp+1evAU3ytdwN/7tv35t5i1vFkifiuWcQMLC/JnLg/RA2s4sYmQwoYhTw/p4GLcP0gO5B3X5w==}
+ '@fullcalendar/interaction@6.1.20':
+ resolution: {integrity: sha512-p6txmc5txL0bMiPaJxe2ip6o0T384TyoD2KGdsU6UjZ5yoBlaY+dg7kxfnYKpYMzEJLG58n+URrHr2PgNL2fyA==}
peerDependencies:
- '@fullcalendar/core': ~6.1.19
+ '@fullcalendar/core': ~6.1.20
'@glimmer/compiler@0.84.3':
resolution: {integrity: sha512-cj9sGlnvExP9httxY6ZMivJRGulyaZ31DddCYB5h6LxupR4Nk2d1nAJCWPLsvuQJ8qR+eYw0y9aiY/VeT0krpQ==}
@@ -3295,8 +3308,8 @@ packages:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
- content-tag@3.1.3:
- resolution: {integrity: sha512-4Kiv9mEroxuMXfWUNUHcljVJgxThCNk7eEswdHMXdzJnkBBaYDqDwzHkoh3F74JJhfU3taJOsgpR6oEGIDg17g==}
+ content-tag@4.1.0:
+ resolution: {integrity: sha512-On6gUuvI1l5MScHO+Xbwjeq1Pk9H6HOipDWkzqGGUGmKpq6K5TRmQuCl1LGSHbdIo2l+lSsgLKrLgCl5kKYA+A==}
content-type@1.0.5:
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
@@ -4155,8 +4168,8 @@ packages:
resolution: {integrity: sha512-OS8TUVG2kQYYwP3netunLVfeijPoOKIs1SvPQRTNOQX4Pu8xGGBEZmrv0U1YTnQn12Eg+p6w/0UdGbUnITjyzw==}
engines: {node: 12.* || >= 14}
- ember-template-imports@4.3.0:
- resolution: {integrity: sha512-jZ5D6KLKU8up/AynZltmKh4lkXBPgTGSPgomprI/55XvIVqn42UNUpEz7ra/mO3QiGODDZOUesbggPe49i38sQ==}
+ ember-template-imports@4.4.0:
+ resolution: {integrity: sha512-HNOHabTEMbRluci1uScvh3ljMDo9E46dHHNcJAIf5yjOhIQ/zN4Y0DVDWrRfcbihlHvt4v/iF69G+8tffC1YkA==}
engines: {node: 16.* || >= 18}
ember-template-lint@5.13.0:
@@ -6914,8 +6927,8 @@ packages:
prosemirror-state@1.4.4:
resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==}
- prosemirror-tables@1.8.3:
- resolution: {integrity: sha512-wbqCR/RlRPRe41a4LFtmhKElzBEfBTdtAYWNIGHM6X2e24NN/MTNUKyXjjphfAfdQce37Kh/5yf765mLPYDe7Q==}
+ prosemirror-tables@1.8.5:
+ resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==}
prosemirror-trailing-node@3.0.0:
resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==}
@@ -9666,7 +9679,7 @@ snapshots:
'@ember/render-modifiers@2.1.0(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))':
dependencies:
- '@embroider/macros': 1.19.5
+ '@embroider/macros': 1.19.6
ember-cli-babel: 7.26.11
ember-modifier-manager-polyfill: 1.2.0(@babel/core@7.28.5)
ember-source: 5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)
@@ -9735,6 +9748,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@embroider/macros@1.19.6':
+ dependencies:
+ '@embroider/shared-internals': 3.0.2
+ assert-never: 1.4.0
+ babel-import-util: 3.0.1
+ ember-cli-babel: 7.26.11
+ find-up: 5.0.0
+ lodash: 4.17.21
+ resolve: 1.22.11
+ semver: 7.7.3
+ transitivePeerDependencies:
+ - supports-color
+
'@embroider/reverse-exports@0.2.0':
dependencies:
mem: 8.1.1
@@ -9786,6 +9812,24 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@embroider/shared-internals@3.0.2':
+ dependencies:
+ babel-import-util: 3.0.1
+ debug: 4.4.3
+ ember-rfc176-data: 0.3.18
+ fs-extra: 9.1.0
+ is-subdir: 1.2.0
+ js-string-escape: 1.0.1
+ lodash: 4.17.21
+ minimatch: 3.1.2
+ pkg-entry-points: 1.1.1
+ resolve-package-path: 4.0.3
+ resolve.exports: 2.0.3
+ semver: 7.7.3
+ typescript-memoize: 1.1.1
+ transitivePeerDependencies:
+ - supports-color
+
'@embroider/test-setup@3.0.3':
dependencies:
lodash: 4.17.21
@@ -9793,7 +9837,7 @@ snapshots:
'@embroider/util@1.13.5(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))':
dependencies:
- '@embroider/macros': 1.19.5
+ '@embroider/macros': 1.19.6
broccoli-funnel: 3.0.8
ember-cli-babel: 7.26.11
ember-source: 5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)
@@ -9865,22 +9909,22 @@ snapshots:
- utf-8-validate
- webpack
- '@fleetbase/ember-ui@0.3.15(@ember/test-helpers@3.3.1(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(webpack@5.104.1))(@glimmer/component@1.1.2(@babel/core@7.28.5))(@glimmer/tracking@1.1.2)(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)))(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(postcss@8.5.6)(rollup@2.79.2)(tracked-built-ins@3.4.0(@babel/core@7.28.5))(webpack@5.104.1)':
+ '@fleetbase/ember-ui@0.3.16(@ember/test-helpers@3.3.1(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(webpack@5.104.1))(@glimmer/component@1.1.2(@babel/core@7.28.5))(@glimmer/tracking@1.1.2)(ember-resolver@11.0.1(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)))(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(postcss@8.5.6)(rollup@2.79.2)(tracked-built-ins@3.4.0(@babel/core@7.28.5))(webpack@5.104.1)':
dependencies:
'@babel/core': 7.28.5
'@ember/render-modifiers': 2.1.0(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))
'@ember/string': 3.1.1
'@embroider/addon': 0.30.0
- '@embroider/macros': 1.19.5
+ '@embroider/macros': 1.19.6
'@fleetbase/ember-accounting': 0.0.1(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))
'@floating-ui/dom': 1.7.4
'@fortawesome/ember-fontawesome': 2.0.0(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(rollup@2.79.2)(webpack@5.104.1)
'@fortawesome/fontawesome-svg-core': 6.4.0
'@fortawesome/free-brands-svg-icons': 6.4.0
'@fortawesome/free-solid-svg-icons': 6.4.0
- '@fullcalendar/core': 6.1.19
- '@fullcalendar/daygrid': 6.1.19(@fullcalendar/core@6.1.19)
- '@fullcalendar/interaction': 6.1.19(@fullcalendar/core@6.1.19)
+ '@fullcalendar/core': 6.1.20
+ '@fullcalendar/daygrid': 6.1.20(@fullcalendar/core@6.1.20)
+ '@fullcalendar/interaction': 6.1.20(@fullcalendar/core@6.1.20)
'@makepanic/ember-power-calendar-date-fns': 0.4.2
'@tailwindcss/forms': 0.5.11(tailwindcss@3.4.19)
'@tiptap/core': 2.27.1(@tiptap/pm@2.27.1)
@@ -10111,17 +10155,17 @@ snapshots:
dependencies:
'@fortawesome/fontawesome-common-types': 6.4.0
- '@fullcalendar/core@6.1.19':
+ '@fullcalendar/core@6.1.20':
dependencies:
preact: 10.12.1
- '@fullcalendar/daygrid@6.1.19(@fullcalendar/core@6.1.19)':
+ '@fullcalendar/daygrid@6.1.20(@fullcalendar/core@6.1.20)':
dependencies:
- '@fullcalendar/core': 6.1.19
+ '@fullcalendar/core': 6.1.20
- '@fullcalendar/interaction@6.1.19(@fullcalendar/core@6.1.19)':
+ '@fullcalendar/interaction@6.1.20(@fullcalendar/core@6.1.20)':
dependencies:
- '@fullcalendar/core': 6.1.19
+ '@fullcalendar/core': 6.1.20
'@glimmer/compiler@0.84.3':
dependencies:
@@ -10629,7 +10673,7 @@ snapshots:
prosemirror-schema-basic: 1.2.4
prosemirror-schema-list: 1.5.1
prosemirror-state: 1.4.4
- prosemirror-tables: 1.8.3
+ prosemirror-tables: 1.8.5
prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4)
prosemirror-transform: 1.10.5
prosemirror-view: 1.41.4
@@ -12590,7 +12634,7 @@ snapshots:
dependencies:
safe-buffer: 5.2.1
- content-tag@3.1.3: {}
+ content-tag@4.1.0: {}
content-type@1.0.5: {}
@@ -12956,7 +13000,7 @@ snapshots:
ember-animated@1.1.4(@ember/test-helpers@3.3.1(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(webpack@5.104.1))(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)):
dependencies:
'@embroider/addon-shim': 1.10.2
- '@embroider/macros': 1.19.5
+ '@embroider/macros': 1.19.6
'@embroider/util': 1.13.5(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))
assert-never: 1.4.0
ember-element-helper: 0.8.8
@@ -13079,7 +13123,7 @@ snapshots:
'@babel/core': 7.28.5
'@ember/test-helpers': 3.3.1(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(webpack@5.104.1)
'@embroider/addon-shim': 1.10.2
- '@embroider/macros': 1.19.5
+ '@embroider/macros': 1.19.6
'@embroider/util': 1.13.5(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))
'@glimmer/component': 1.1.2(@babel/core@7.28.5)
'@glimmer/tracking': 1.1.2
@@ -13768,7 +13812,7 @@ snapshots:
ember-cli-htmlbars: 6.3.0
ember-element-helper: 0.8.8
ember-source: 5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1)
- ember-template-imports: 4.3.0
+ ember-template-imports: 4.4.0
transitivePeerDependencies:
- '@glint/template'
- supports-color
@@ -13820,7 +13864,7 @@ snapshots:
'@ember/test-helpers': 3.3.1(@babel/core@7.28.5)(ember-source@5.4.1(@babel/core@7.28.5)(@glimmer/component@1.1.2(@babel/core@7.28.5))(rsvp@4.8.5)(webpack@5.104.1))(webpack@5.104.1)
'@ember/test-waiters': 3.1.0
'@embroider/addon-shim': 1.10.2
- '@embroider/macros': 1.19.5
+ '@embroider/macros': 1.19.6
'@glimmer/component': 1.1.2(@babel/core@7.28.5)
'@glimmer/tracking': 1.1.2
ember-auto-import: 2.12.0(webpack@5.104.1)
@@ -14256,10 +14300,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
- ember-template-imports@4.3.0:
+ ember-template-imports@4.4.0:
dependencies:
broccoli-stew: 3.0.0
- content-tag: 3.1.3
+ content-tag: 4.1.0
ember-cli-version-checker: 5.1.2
transitivePeerDependencies:
- supports-color
@@ -17478,7 +17522,7 @@ snapshots:
prosemirror-transform: 1.10.5
prosemirror-view: 1.41.4
- prosemirror-tables@1.8.3:
+ prosemirror-tables@1.8.5:
dependencies:
prosemirror-keymap: 1.2.3
prosemirror-model: 1.25.4
diff --git a/server/src/Http/Controllers/DataController.php b/server/src/Http/Controllers/DataController.php
index 789d876..93e323f 100644
--- a/server/src/Http/Controllers/DataController.php
+++ b/server/src/Http/Controllers/DataController.php
@@ -138,6 +138,35 @@ public function createFolder(Request $request)
'parent_url' => $parentUrl,
]);
+ // Check if parent URL is writable before attempting folder creation
+ $aclService = app(\Fleetbase\Solid\Services\AclService::class);
+
+ if (!$aclService->isWritable($identity, $parentUrl)) {
+ Log::warning('[FOLDER CREATE] Location not writable', [
+ 'parent_url' => $parentUrl,
+ 'webid' => $webId,
+ ]);
+
+ // Find writable locations
+ $writableLocations = $aclService->findWritableLocations($identity, $profile);
+
+ if (!empty($writableLocations)) {
+ $suggestion = array_values($writableLocations)[0];
+ return response()->json([
+ 'success' => false,
+ 'error' => 'Cannot create folder at specified location. You do not have write permissions.',
+ 'suggestion' => "Try creating the folder at: {$suggestion}",
+ 'writable_locations' => $writableLocations,
+ ], 403);
+ } else {
+ return response()->json([
+ 'success' => false,
+ 'error' => 'No writable locations found in your pod.',
+ 'help' => 'You may need to configure ACL permissions. See: https://docs.solidproject.org/managing-permissions',
+ ], 403);
+ }
+ }
+
// Use POST with Slug header (Solid Protocol standard)
$result = $this->podService->createFolder($identity, $parentUrl, $folderName);
@@ -237,6 +266,34 @@ public function importResources(Request $request)
'resource_types' => $resourceTypes,
]);
+ // Check if pod URL is writable before importing
+ $aclService = app(\Fleetbase\Solid\Services\AclService::class);
+
+ if (!$aclService->isWritable($identity, $podUrl)) {
+ Log::warning('[IMPORT RESOURCES] Pod root not writable', [
+ 'pod_url' => $podUrl,
+ 'webid' => $webId,
+ ]);
+
+ // Find writable locations
+ $writableLocations = $aclService->findWritableLocations($identity, $profile);
+
+ if (!empty($writableLocations)) {
+ return response()->json([
+ 'success' => false,
+ 'error' => 'Cannot import resources to pod root. You do not have write permissions.',
+ 'writable_locations' => $writableLocations,
+ 'help' => 'Resources can only be imported to writable locations.',
+ ], 403);
+ } else {
+ return response()->json([
+ 'success' => false,
+ 'error' => 'No writable locations found in your pod.',
+ 'help' => 'You may need to configure ACL permissions. See: https://docs.solidproject.org/managing-permissions',
+ ], 403);
+ }
+ }
+
$result = $this->resourceSyncService->importResources($identity, $podUrl, $resourceTypes);
return response()->json([
diff --git a/server/src/Services/AclService.php b/server/src/Services/AclService.php
index f99ba80..a3ce529 100644
--- a/server/src/Services/AclService.php
+++ b/server/src/Services/AclService.php
@@ -143,4 +143,263 @@ public function ensureWritePermissions(SolidIdentity $identity, string $podUrl,
Log::info('[ACL NEEDS UPDATE]', ['pod_url' => $podUrl]);
return $this->grantWritePermissions($identity, $podUrl, $webId);
}
+
+ /**
+ * Ensure a folder has proper ACL permissions after creation.
+ *
+ * @param SolidIdentity $identity
+ * @param string $folderUrl The folder URL (must end with /)
+ * @param string $webId The WebID to grant permissions to
+ * @return bool
+ */
+ public function ensureFolderPermissions(SolidIdentity $identity, string $folderUrl, string $webId): bool
+ {
+ try {
+ // Ensure folder URL ends with /
+ $folderUrl = rtrim($folderUrl, '/') . '/';
+ $aclUrl = $folderUrl . '.acl';
+
+ Log::info('[ACL] Ensuring folder permissions', [
+ 'folder_url' => $folderUrl,
+ 'acl_url' => $aclUrl,
+ 'webid' => $webId,
+ ]);
+
+ // Check if ACL already exists and has write permissions
+ if ($this->hasFolderWritePermissions($identity, $folderUrl, $webId)) {
+ Log::info('[ACL] Folder already has write permissions', ['folder_url' => $folderUrl]);
+ return true;
+ }
+
+ // Create ACL with full permissions for the owner
+ $aclContent = $this->generateFolderAcl($folderUrl, $webId);
+
+ return $this->createFolderAcl($identity, $aclUrl, $aclContent);
+ } catch (\Throwable $e) {
+ Log::error('[ACL] Failed to ensure folder permissions', [
+ 'folder_url' => $folderUrl,
+ 'error' => $e->getMessage(),
+ ]);
+ return false;
+ }
+ }
+
+ /**
+ * Check if a folder has write permissions.
+ *
+ * @param SolidIdentity $identity
+ * @param string $folderUrl
+ * @param string $webId
+ * @return bool
+ */
+ protected function hasFolderWritePermissions(SolidIdentity $identity, string $folderUrl, string $webId): bool
+ {
+ try {
+ $response = $identity->request('head', $folderUrl);
+
+ if (!$response->successful()) {
+ return false;
+ }
+
+ // Check WAC-Allow header
+ $wacAllow = $response->header('WAC-Allow');
+
+ if ($wacAllow) {
+ Log::debug('[ACL] WAC-Allow header', [
+ 'folder_url' => $folderUrl,
+ 'wac_allow' => $wacAllow,
+ ]);
+
+ // Parse WAC-Allow header: user="read write", public="read"
+ if (preg_match('/user="([^"]*)"/i', $wacAllow, $matches)) {
+ $userModes = strtolower($matches[1]);
+ return str_contains($userModes, 'write') || str_contains($userModes, 'append');
+ }
+ }
+
+ return false;
+ } catch (\Throwable $e) {
+ Log::debug('[ACL] Error checking folder permissions', [
+ 'folder_url' => $folderUrl,
+ 'error' => $e->getMessage(),
+ ]);
+ return false;
+ }
+ }
+
+ /**
+ * Create an ACL file for a folder.
+ *
+ * @param SolidIdentity $identity
+ * @param string $aclUrl
+ * @param string $aclContent
+ * @return bool
+ */
+ protected function createFolderAcl(SolidIdentity $identity, string $aclUrl, string $aclContent): bool
+ {
+ try {
+ $response = $identity->request('put', $aclUrl, $aclContent, [
+ 'headers' => [
+ 'Content-Type' => 'text/turtle',
+ ],
+ ]);
+
+ if ($response->successful()) {
+ Log::info('[ACL] Folder ACL created successfully', [
+ 'acl_url' => $aclUrl,
+ 'status' => $response->status(),
+ ]);
+ return true;
+ }
+
+ Log::error('[ACL] Failed to create folder ACL', [
+ 'acl_url' => $aclUrl,
+ 'status' => $response->status(),
+ 'body' => $response->body(),
+ ]);
+
+ return false;
+ } catch (\Throwable $e) {
+ Log::error('[ACL] Error creating folder ACL', [
+ 'acl_url' => $aclUrl,
+ 'error' => $e->getMessage(),
+ ]);
+ return false;
+ }
+ }
+
+ /**
+ * Generate ACL content for a folder with full owner permissions.
+ *
+ * @param string $folderUrl The folder URL
+ * @param string $webId The WebID to grant permissions to
+ * @return string
+ */
+ protected function generateFolderAcl(string $folderUrl, string $webId): string
+ {
+ return <<.
+
+<#owner>
+ a acl:Authorization;
+ acl:agent <{$webId}>;
+ acl:accessTo <./>;
+ acl:default <./>;
+ acl:mode acl:Read, acl:Write, acl:Control.
+TURTLE;
+ }
+
+ /**
+ * Check if a specific URL is writable (has write or append permissions).
+ *
+ * @param SolidIdentity $identity
+ * @param string $url
+ * @return bool
+ */
+ public function isWritable(SolidIdentity $identity, string $url): bool
+ {
+ try {
+ $response = $identity->request('head', $url);
+
+ if (!$response->successful()) {
+ return false;
+ }
+
+ $wacAllow = $response->header('WAC-Allow');
+
+ if ($wacAllow && preg_match('/user="([^"]*)"/i', $wacAllow, $matches)) {
+ $modes = strtolower($matches[1]);
+ $isWritable = str_contains($modes, 'write') || str_contains($modes, 'append');
+
+ Log::debug('[ACL] Writable check', [
+ 'url' => $url,
+ 'wac_allow' => $wacAllow,
+ 'is_writable' => $isWritable,
+ ]);
+
+ return $isWritable;
+ }
+
+ return false;
+ } catch (\Throwable $e) {
+ Log::debug('[ACL] Writable check failed', [
+ 'url' => $url,
+ 'error' => $e->getMessage(),
+ ]);
+ return false;
+ }
+ }
+
+ /**
+ * Find writable storage locations from user profile.
+ *
+ * @param SolidIdentity $identity
+ * @param array $profile
+ * @return array
+ */
+ public function findWritableLocations(SolidIdentity $identity, array $profile): array
+ {
+ $writableLocations = [];
+ $webId = $profile['webid'] ?? null;
+
+ if (!$webId) {
+ return $writableLocations;
+ }
+
+ // Get pod URL from WebID
+ $podUrl = $this->podService->getPodUrlFromWebId($webId);
+
+ // Check common storage locations
+ $commonLocations = [
+ 'public' => rtrim($podUrl, '/') . '/public/',
+ 'private' => rtrim($podUrl, '/') . '/private/',
+ 'inbox' => rtrim($podUrl, '/') . '/inbox/',
+ ];
+
+ foreach ($commonLocations as $name => $url) {
+ if ($this->isWritable($identity, $url)) {
+ $writableLocations[$name] = $url;
+ }
+ }
+
+ // Check storage locations from profile
+ foreach ($profile['storage_locations'] ?? [] as $storage) {
+ $storageUrl = $this->resolveStorageUrl($storage, $webId, $podUrl);
+ if ($storageUrl && $this->isWritable($identity, $storageUrl)) {
+ $writableLocations['storage_' . count($writableLocations)] = $storageUrl;
+ }
+ }
+
+ Log::info('[ACL] Found writable locations', [
+ 'count' => count($writableLocations),
+ 'locations' => $writableLocations,
+ ]);
+
+ return $writableLocations;
+ }
+
+ /**
+ * Resolve a storage URL from profile data.
+ *
+ * @param string $storage
+ * @param string $webId
+ * @param string $podUrl
+ * @return string|null
+ */
+ protected function resolveStorageUrl(string $storage, string $webId, string $podUrl): ?string
+ {
+ // Handle relative URLs
+ if ($storage === '../' || $storage === './') {
+ return $podUrl;
+ }
+
+ // Handle absolute URLs
+ if (str_starts_with($storage, 'http://') || str_starts_with($storage, 'https://')) {
+ return $storage;
+ }
+
+ // Handle relative paths
+ $webIdBase = dirname($webId);
+ return rtrim($webIdBase, '/') . '/' . ltrim($storage, '/');
+ }
}
diff --git a/server/src/Services/PodService.php b/server/src/Services/PodService.php
index b07690d..13357da 100644
--- a/server/src/Services/PodService.php
+++ b/server/src/Services/PodService.php
@@ -712,20 +712,58 @@ private function parseContainerContents(string $content): array
{
$items = [];
- // Parse contained resources
+ // Parse contained resources with ldp:contains
if (preg_match_all('/ldp:contains\s+<([^>]+)>/', $content, $matches)) {
foreach ($matches[1] as $resourceUrl) {
- $items[] = [
+ $item = [
'url' => $resourceUrl,
'name' => $this->extractPodName($resourceUrl),
'type' => substr($resourceUrl, -1) === '/' ? 'container' : 'resource',
];
+
+ // Try to extract additional metadata for this resource
+ $item = array_merge($item, $this->extractResourceMetadata($content, $resourceUrl));
+
+ $items[] = $item;
}
}
return $items;
}
+ /**
+ * Extract metadata for a specific resource from Turtle content.
+ */
+ private function extractResourceMetadata(string $content, string $resourceUrl): array
+ {
+ $metadata = [];
+
+ // Escape special regex characters in URL
+ $escapedUrl = preg_quote($resourceUrl, '/');
+
+ // Extract resource type (e.g., ldp:BasicContainer, foaf:Document)
+ if (preg_match('/<' . $escapedUrl . '>\s+a\s+([^;\s]+)/', $content, $matches)) {
+ $metadata['rdf_type'] = trim($matches[1]);
+ }
+
+ // Extract dc:title
+ if (preg_match('/<' . $escapedUrl . '>.*?dc:title\s+"([^"]+)"/', $content, $matches)) {
+ $metadata['title'] = $matches[1];
+ }
+
+ // Extract dc:modified or posix:mtime
+ if (preg_match('/<' . $escapedUrl . '>.*?(?:dc:modified|posix:mtime)\s+(\d+)/', $content, $matches)) {
+ $metadata['modified'] = (int)$matches[1];
+ }
+
+ // Extract posix:size
+ if (preg_match('/<' . $escapedUrl . '>.*?posix:size\s+(\d+)/', $content, $matches)) {
+ $metadata['size'] = (int)$matches[1];
+ }
+
+ return $metadata;
+ }
+
/**
* Generate pod metadata in Turtle format.
*/
@@ -804,6 +842,15 @@ public function createFolder(SolidIdentity $identity, string $parentUrl, string
'folder_url' => $createdUrl,
'status' => $response->status(),
]);
+
+ // Ensure the folder has proper ACL permissions
+ $aclService = app(AclService::class);
+ $webId = $identity->webid;
+
+ if ($webId) {
+ $aclService->ensureFolderPermissions($identity, $createdUrl, $webId);
+ }
+
return true;
}
diff --git a/server/src/Services/ResourceSyncService.php b/server/src/Services/ResourceSyncService.php
index d854d19..d37e771 100644
--- a/server/src/Services/ResourceSyncService.php
+++ b/server/src/Services/ResourceSyncService.php
@@ -299,6 +299,14 @@ protected function createContainer(SolidIdentity $identity, string $containerUrl
'url' => $containerUrl,
'status' => $response->status(),
]);
+
+ // Ensure the container has proper ACL permissions
+ $aclService = app(AclService::class);
+ $webId = $identity->webid;
+
+ if ($webId) {
+ $aclService->ensureFolderPermissions($identity, $containerUrl, $webId);
+ }
} catch (\Throwable $e) {
// Container might already exist, that's okay
Log::debug('[CONTAINER CREATION SKIPPED]', [