@object-ui/app-shell 6.0.2 → 6.0.3
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
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @object-ui/app-shell — Changelog
|
|
2
2
|
|
|
3
|
+
## 6.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 58f0af6: Fix marketplace install dialog showing "No environments found" even when the
|
|
8
|
+
signed-in user has cloud environments. Cloud's data API returns rows under
|
|
9
|
+
`records`, not `data`/`items`; the dialog now reads the correct key. As a
|
|
10
|
+
hardening pass, also filter `sys_member` rows by the caller's session
|
|
11
|
+
`user_id` so a leaky data endpoint cannot widen the install target list to
|
|
12
|
+
other tenants' organizations.
|
|
13
|
+
- @object-ui/types@6.0.3
|
|
14
|
+
- @object-ui/core@6.0.3
|
|
15
|
+
- @object-ui/i18n@6.0.3
|
|
16
|
+
- @object-ui/react@6.0.3
|
|
17
|
+
- @object-ui/components@6.0.3
|
|
18
|
+
- @object-ui/fields@6.0.3
|
|
19
|
+
- @object-ui/layout@6.0.3
|
|
20
|
+
- @object-ui/data-objectstack@6.0.3
|
|
21
|
+
- @object-ui/auth@6.0.3
|
|
22
|
+
- @object-ui/permissions@6.0.3
|
|
23
|
+
- @object-ui/collaboration@6.0.3
|
|
24
|
+
- @object-ui/providers@6.0.3
|
|
25
|
+
|
|
3
26
|
## 6.0.2
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -108,6 +108,11 @@ export declare function listCloudEnvironments(): Promise<CloudEnvironment[]>;
|
|
|
108
108
|
*
|
|
109
109
|
* Returns an empty set on 401 / network failure so the install dialog
|
|
110
110
|
* can render a clean "no installable environments" state.
|
|
111
|
+
*
|
|
112
|
+
* Hardening: we *always* re-filter rows by the caller's session
|
|
113
|
+
* `user_id` because the data API currently returns sys_member rows
|
|
114
|
+
* without per-caller scoping. Without this, the dialog would pick up
|
|
115
|
+
* every org in the system and offer their envs as install targets.
|
|
111
116
|
*/
|
|
112
117
|
export declare function listInstallableOrgIds(): Promise<Set<string>>;
|
|
113
118
|
export declare function cloudInstallDeepLink(packageId: string): string;
|
|
@@ -94,7 +94,9 @@ export async function listCloudEnvironments() {
|
|
|
94
94
|
throw err;
|
|
95
95
|
}
|
|
96
96
|
const payload = await res.json().catch(() => ({}));
|
|
97
|
-
|
|
97
|
+
// Cloud's data API returns `{ object, records, total, hasMore }`.
|
|
98
|
+
// We keep `data` / `items` as fallbacks for older builds.
|
|
99
|
+
const rows = payload?.records ?? payload?.data ?? payload?.items ?? payload ?? [];
|
|
98
100
|
return Array.isArray(rows) ? rows : [];
|
|
99
101
|
}
|
|
100
102
|
/**
|
|
@@ -105,10 +107,30 @@ export async function listCloudEnvironments() {
|
|
|
105
107
|
*
|
|
106
108
|
* Returns an empty set on 401 / network failure so the install dialog
|
|
107
109
|
* can render a clean "no installable environments" state.
|
|
110
|
+
*
|
|
111
|
+
* Hardening: we *always* re-filter rows by the caller's session
|
|
112
|
+
* `user_id` because the data API currently returns sys_member rows
|
|
113
|
+
* without per-caller scoping. Without this, the dialog would pick up
|
|
114
|
+
* every org in the system and offer their envs as install targets.
|
|
108
115
|
*/
|
|
109
116
|
export async function listInstallableOrgIds() {
|
|
110
117
|
const base = getCloudBase() || SERVER_URL;
|
|
111
|
-
|
|
118
|
+
let meId = null;
|
|
119
|
+
try {
|
|
120
|
+
const meRes = await fetch(`${base}/api/v1/auth/get-session`, {
|
|
121
|
+
credentials: 'include',
|
|
122
|
+
headers: { 'Accept': 'application/json' },
|
|
123
|
+
});
|
|
124
|
+
if (meRes.ok) {
|
|
125
|
+
const meBody = await meRes.json().catch(() => ({}));
|
|
126
|
+
meId = meBody?.user?.id ?? null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
/* fall through — meId stays null and we return empty set */
|
|
131
|
+
}
|
|
132
|
+
if (!meId)
|
|
133
|
+
return new Set();
|
|
112
134
|
const url = `${base}/api/v1/data/sys_member?limit=200`;
|
|
113
135
|
let payload = null;
|
|
114
136
|
try {
|
|
@@ -123,11 +145,14 @@ export async function listInstallableOrgIds() {
|
|
|
123
145
|
catch {
|
|
124
146
|
return new Set();
|
|
125
147
|
}
|
|
126
|
-
const rows = payload?.data ?? payload?.items ?? payload ?? [];
|
|
148
|
+
const rows = payload?.records ?? payload?.data ?? payload?.items ?? payload ?? [];
|
|
127
149
|
if (!Array.isArray(rows))
|
|
128
150
|
return new Set();
|
|
129
151
|
const ids = new Set();
|
|
130
152
|
for (const row of rows) {
|
|
153
|
+
const rowUserId = String(row?.user_id ?? row?.userId ?? '');
|
|
154
|
+
if (rowUserId !== meId)
|
|
155
|
+
continue;
|
|
131
156
|
const role = String(row?.role ?? '').toLowerCase();
|
|
132
157
|
const orgId = row?.organization_id ?? row?.organizationId;
|
|
133
158
|
if (orgId && (role === 'owner' || role === 'admin')) {
|
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
* Resolve the absolute URL of the console "home" route used after switching
|
|
3
3
|
* the active organization.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* History:
|
|
6
|
+
* - `${origin}${import.meta.env.BASE_URL}home` broke portable builds
|
|
7
|
+
* (`base: './'`), producing `https://host./home` — trailing-dot host.
|
|
8
|
+
* - `new URL('home', document.baseURI)` fixed that, but `document.baseURI`
|
|
9
|
+
* falls back to the current page URL when no `<base>` tag is present.
|
|
10
|
+
* From `/home/home/` that resolves to `/home/home/home`, and each
|
|
11
|
+
* subsequent navigation appended another `/home` segment.
|
|
12
12
|
*
|
|
13
|
-
* The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* `<base>` entirely (falls back to the current document URL's directory).
|
|
13
|
+
* The robust resolution: read `<base href>` explicitly. When present it
|
|
14
|
+
* carries the deployment mount (`/_console/`, `/`, or `./`); when absent
|
|
15
|
+
* we resolve against the document origin root, which is independent of the
|
|
16
|
+
* current SPA route.
|
|
18
17
|
*/
|
|
19
18
|
export declare function resolveHomeUrl(baseURI?: string): string;
|
|
@@ -2,20 +2,26 @@
|
|
|
2
2
|
* Resolve the absolute URL of the console "home" route used after switching
|
|
3
3
|
* the active organization.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* History:
|
|
6
|
+
* - `${origin}${import.meta.env.BASE_URL}home` broke portable builds
|
|
7
|
+
* (`base: './'`), producing `https://host./home` — trailing-dot host.
|
|
8
|
+
* - `new URL('home', document.baseURI)` fixed that, but `document.baseURI`
|
|
9
|
+
* falls back to the current page URL when no `<base>` tag is present.
|
|
10
|
+
* From `/home/home/` that resolves to `/home/home/home`, and each
|
|
11
|
+
* subsequent navigation appended another `/home` segment.
|
|
12
12
|
*
|
|
13
|
-
* The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* `<base>` entirely (falls back to the current document URL's directory).
|
|
13
|
+
* The robust resolution: read `<base href>` explicitly. When present it
|
|
14
|
+
* carries the deployment mount (`/_console/`, `/`, or `./`); when absent
|
|
15
|
+
* we resolve against the document origin root, which is independent of the
|
|
16
|
+
* current SPA route.
|
|
18
17
|
*/
|
|
19
|
-
export function resolveHomeUrl(baseURI
|
|
20
|
-
|
|
18
|
+
export function resolveHomeUrl(baseURI) {
|
|
19
|
+
if (baseURI !== undefined) {
|
|
20
|
+
return new URL('home', baseURI).toString();
|
|
21
|
+
}
|
|
22
|
+
const baseHref = document.querySelector('base')?.getAttribute('href');
|
|
23
|
+
const root = baseHref
|
|
24
|
+
? new URL(baseHref, window.location.origin)
|
|
25
|
+
: new URL('/', window.location.origin);
|
|
26
|
+
return new URL('home', root).toString();
|
|
21
27
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/app-shell",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Minimal application shell for ObjectUI - framework-agnostic rendering engine",
|
|
@@ -28,35 +28,35 @@
|
|
|
28
28
|
"@sentry/react": "^8.55.2",
|
|
29
29
|
"lucide-react": "^1.16.0",
|
|
30
30
|
"sonner": "^2.0.7",
|
|
31
|
-
"@object-ui/auth": "6.0.
|
|
32
|
-
"@object-ui/collaboration": "6.0.
|
|
33
|
-
"@object-ui/components": "6.0.
|
|
34
|
-
"@object-ui/core": "6.0.
|
|
35
|
-
"@object-ui/data-objectstack": "6.0.
|
|
36
|
-
"@object-ui/fields": "6.0.
|
|
37
|
-
"@object-ui/i18n": "6.0.
|
|
38
|
-
"@object-ui/layout": "6.0.
|
|
39
|
-
"@object-ui/permissions": "6.0.
|
|
40
|
-
"@object-ui/providers": "6.0.
|
|
41
|
-
"@object-ui/react": "6.0.
|
|
42
|
-
"@object-ui/types": "6.0.
|
|
31
|
+
"@object-ui/auth": "6.0.3",
|
|
32
|
+
"@object-ui/collaboration": "6.0.3",
|
|
33
|
+
"@object-ui/components": "6.0.3",
|
|
34
|
+
"@object-ui/core": "6.0.3",
|
|
35
|
+
"@object-ui/data-objectstack": "6.0.3",
|
|
36
|
+
"@object-ui/fields": "6.0.3",
|
|
37
|
+
"@object-ui/i18n": "6.0.3",
|
|
38
|
+
"@object-ui/layout": "6.0.3",
|
|
39
|
+
"@object-ui/permissions": "6.0.3",
|
|
40
|
+
"@object-ui/providers": "6.0.3",
|
|
41
|
+
"@object-ui/react": "6.0.3",
|
|
42
|
+
"@object-ui/types": "6.0.3"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"react": "^18.0.0 || ^19.0.0",
|
|
46
46
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
47
47
|
"react-router-dom": "^6.0.0 || ^7.0.0",
|
|
48
|
-
"@object-ui/plugin-calendar": "^6.0.
|
|
49
|
-
"@object-ui/plugin-charts": "^6.0.
|
|
50
|
-
"@object-ui/plugin-chatbot": "^6.0.
|
|
51
|
-
"@object-ui/plugin-dashboard": "^6.0.
|
|
52
|
-
"@object-ui/plugin-designer": "^6.0.
|
|
53
|
-
"@object-ui/plugin-detail": "^6.0.
|
|
54
|
-
"@object-ui/plugin-form": "^6.0.
|
|
55
|
-
"@object-ui/plugin-grid": "^6.0.
|
|
56
|
-
"@object-ui/plugin-kanban": "^6.0.
|
|
57
|
-
"@object-ui/plugin-list": "^6.0.
|
|
58
|
-
"@object-ui/plugin-report": "^6.0.
|
|
59
|
-
"@object-ui/plugin-view": "^6.0.
|
|
48
|
+
"@object-ui/plugin-calendar": "^6.0.3",
|
|
49
|
+
"@object-ui/plugin-charts": "^6.0.3",
|
|
50
|
+
"@object-ui/plugin-chatbot": "^6.0.3",
|
|
51
|
+
"@object-ui/plugin-dashboard": "^6.0.3",
|
|
52
|
+
"@object-ui/plugin-designer": "^6.0.3",
|
|
53
|
+
"@object-ui/plugin-detail": "^6.0.3",
|
|
54
|
+
"@object-ui/plugin-form": "^6.0.3",
|
|
55
|
+
"@object-ui/plugin-grid": "^6.0.3",
|
|
56
|
+
"@object-ui/plugin-kanban": "^6.0.3",
|
|
57
|
+
"@object-ui/plugin-list": "^6.0.3",
|
|
58
|
+
"@object-ui/plugin-report": "^6.0.3",
|
|
59
|
+
"@object-ui/plugin-view": "^6.0.3"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/node": "^25.9.0",
|