@jskit-ai/users-web 0.1.46 → 0.1.48
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/package.descriptor.mjs +7 -7
- package/package.json +7 -7
- package/src/client/components/MembersAdminClientElement.vue +5 -4
- package/src/client/components/WorkspaceMembersClientElement.vue +18 -16
- package/src/client/composables/account-settings/accountSettingsRuntimeHelpers.js +4 -3
- package/src/client/lib/bootstrap.js +6 -4
- package/test/bootstrap.test.js +2 -2
- package/test/bootstrapPlacementRuntime.test.js +31 -31
package/package.descriptor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
packageVersion: 1,
|
|
3
3
|
packageId: "@jskit-ai/users-web",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.48",
|
|
5
5
|
kind: "runtime",
|
|
6
6
|
description: "Users web module: account/profile UI plus shared shell link components.",
|
|
7
7
|
dependsOn: [
|
|
@@ -153,12 +153,12 @@ export default Object.freeze({
|
|
|
153
153
|
runtime: {
|
|
154
154
|
"@tanstack/vue-query": "5.92.12",
|
|
155
155
|
"@mdi/js": "^7.4.47",
|
|
156
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
157
|
-
"@jskit-ai/realtime": "0.1.
|
|
158
|
-
"@jskit-ai/kernel": "0.1.
|
|
159
|
-
"@jskit-ai/shell-web": "0.1.
|
|
160
|
-
"@jskit-ai/uploads-image-web": "0.1.
|
|
161
|
-
"@jskit-ai/users-core": "0.1.
|
|
156
|
+
"@jskit-ai/http-runtime": "0.1.32",
|
|
157
|
+
"@jskit-ai/realtime": "0.1.32",
|
|
158
|
+
"@jskit-ai/kernel": "0.1.33",
|
|
159
|
+
"@jskit-ai/shell-web": "0.1.32",
|
|
160
|
+
"@jskit-ai/uploads-image-web": "0.1.11",
|
|
161
|
+
"@jskit-ai/users-core": "0.1.43",
|
|
162
162
|
vuetify: "^4.0.0"
|
|
163
163
|
},
|
|
164
164
|
dev: {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/users-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.48",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@tanstack/vue-query": "5.92.12",
|
|
30
30
|
"@mdi/js": "^7.4.47",
|
|
31
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
32
|
-
"@jskit-ai/kernel": "0.1.
|
|
33
|
-
"@jskit-ai/realtime": "0.1.
|
|
34
|
-
"@jskit-ai/shell-web": "0.1.
|
|
35
|
-
"@jskit-ai/uploads-image-web": "0.1.
|
|
36
|
-
"@jskit-ai/users-core": "0.1.
|
|
31
|
+
"@jskit-ai/http-runtime": "0.1.32",
|
|
32
|
+
"@jskit-ai/kernel": "0.1.33",
|
|
33
|
+
"@jskit-ai/realtime": "0.1.32",
|
|
34
|
+
"@jskit-ai/shell-web": "0.1.32",
|
|
35
|
+
"@jskit-ai/uploads-image-web": "0.1.11",
|
|
36
|
+
"@jskit-ai/users-core": "0.1.43",
|
|
37
37
|
"vuetify": "^4.0.0"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -168,6 +168,7 @@
|
|
|
168
168
|
<script setup>
|
|
169
169
|
import { computed, toRefs, unref } from "vue";
|
|
170
170
|
import { formatDateTime as formatKernelDateTime } from "@jskit-ai/kernel/shared/support";
|
|
171
|
+
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
171
172
|
import { requireBoolean, requireFunction, requireRecord } from "../support/contractGuards.js";
|
|
172
173
|
|
|
173
174
|
const props = defineProps({
|
|
@@ -188,11 +189,11 @@ const props = defineProps({
|
|
|
188
189
|
required: true
|
|
189
190
|
},
|
|
190
191
|
revokeInviteId: {
|
|
191
|
-
type:
|
|
192
|
+
type: String,
|
|
192
193
|
required: true
|
|
193
194
|
},
|
|
194
195
|
removeMemberUserId: {
|
|
195
|
-
type:
|
|
196
|
+
type: String,
|
|
196
197
|
required: true
|
|
197
198
|
},
|
|
198
199
|
status: {
|
|
@@ -352,11 +353,11 @@ function isMemberRemoveLocked(member) {
|
|
|
352
353
|
}
|
|
353
354
|
|
|
354
355
|
function isRevokeInviteLoading(inviteId) {
|
|
355
|
-
return isRevokingInvite.value && revokeInviteId.value ===
|
|
356
|
+
return isRevokingInvite.value && revokeInviteId.value === normalizeRecordId(inviteId, { fallback: "" });
|
|
356
357
|
}
|
|
357
358
|
|
|
358
359
|
function isRemoveMemberLoading(memberUserId) {
|
|
359
|
-
return isRemovingMember.value && removeMemberUserId.value ===
|
|
360
|
+
return isRemovingMember.value && removeMemberUserId.value === normalizeRecordId(memberUserId, { fallback: "" });
|
|
360
361
|
}
|
|
361
362
|
|
|
362
363
|
async function onSubmitInvite() {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
<script setup>
|
|
22
22
|
import { computed, reactive, ref, watch } from "vue";
|
|
23
23
|
import { formatDateTime } from "@jskit-ai/kernel/shared/support";
|
|
24
|
+
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
24
25
|
import MembersAdminClientElement from "./MembersAdminClientElement.vue";
|
|
25
26
|
import { useCommand } from "../composables/useCommand.js";
|
|
26
27
|
import { useList } from "../composables/records/useList.js";
|
|
@@ -61,8 +62,8 @@ const collections = reactive({
|
|
|
61
62
|
const inviteFeedback = useUiFeedback();
|
|
62
63
|
const membersFeedback = useUiFeedback();
|
|
63
64
|
const teamFeedback = useUiFeedback();
|
|
64
|
-
const revokeInviteId = ref(
|
|
65
|
-
const removeMemberUserId = ref(
|
|
65
|
+
const revokeInviteId = ref("");
|
|
66
|
+
const removeMemberUserId = ref("");
|
|
66
67
|
|
|
67
68
|
const { route, currentSurfaceId, workspaceSlugFromRoute, mergePlacementContext } =
|
|
68
69
|
useWorkspaceRouteContext();
|
|
@@ -83,7 +84,8 @@ const workspaceInvitesApiPath = computed(() =>
|
|
|
83
84
|
);
|
|
84
85
|
|
|
85
86
|
function workspaceMembersPath(memberId) {
|
|
86
|
-
|
|
87
|
+
const normalizedMemberId = encodeURIComponent(String(memberId || "").trim());
|
|
88
|
+
return `${workspaceMembersApiPath.value}/${normalizedMemberId}`;
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
function workspaceInvitePath(inviteId) {
|
|
@@ -145,8 +147,8 @@ function resetViewState() {
|
|
|
145
147
|
collections.members = [];
|
|
146
148
|
collections.invites = [];
|
|
147
149
|
clearRoleOptions();
|
|
148
|
-
revokeInviteId.value =
|
|
149
|
-
removeMemberUserId.value =
|
|
150
|
+
revokeInviteId.value = "";
|
|
151
|
+
removeMemberUserId.value = "";
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
function toRoleTitle(roleSid) {
|
|
@@ -223,7 +225,7 @@ function normalizeMembers(entries) {
|
|
|
223
225
|
return source.map((entry) => {
|
|
224
226
|
const value = entry && typeof entry === "object" ? entry : {};
|
|
225
227
|
return {
|
|
226
|
-
userId:
|
|
228
|
+
userId: normalizeRecordId(value.userId, { fallback: "" }),
|
|
227
229
|
roleSid: String(value.roleSid || "").trim().toLowerCase(),
|
|
228
230
|
status: String(value.status || "").trim().toLowerCase(),
|
|
229
231
|
displayName: String(value.displayName || "").trim(),
|
|
@@ -238,12 +240,12 @@ function normalizeInvites(entries) {
|
|
|
238
240
|
return source.map((entry) => {
|
|
239
241
|
const value = entry && typeof entry === "object" ? entry : {};
|
|
240
242
|
return {
|
|
241
|
-
id:
|
|
243
|
+
id: normalizeRecordId(value.id, { fallback: "" }),
|
|
242
244
|
email: String(value.email || "").trim().toLowerCase(),
|
|
243
245
|
roleSid: String(value.roleSid || "").trim().toLowerCase(),
|
|
244
246
|
status: String(value.status || "").trim().toLowerCase(),
|
|
245
247
|
expiresAt: value.expiresAt || "",
|
|
246
|
-
invitedByUserId: value.invitedByUserId
|
|
248
|
+
invitedByUserId: normalizeRecordId(value.invitedByUserId, { fallback: null })
|
|
247
249
|
};
|
|
248
250
|
});
|
|
249
251
|
}
|
|
@@ -576,7 +578,7 @@ async function submitRevokeInvite(inviteId) {
|
|
|
576
578
|
return;
|
|
577
579
|
}
|
|
578
580
|
|
|
579
|
-
revokeInviteId.value =
|
|
581
|
+
revokeInviteId.value = normalizeRecordId(inviteId, { fallback: "" });
|
|
580
582
|
teamFeedback.clear();
|
|
581
583
|
|
|
582
584
|
try {
|
|
@@ -591,7 +593,7 @@ async function submitRevokeInvite(inviteId) {
|
|
|
591
593
|
} catch (error) {
|
|
592
594
|
teamFeedback.error(error, "Unable to revoke invite.");
|
|
593
595
|
} finally {
|
|
594
|
-
revokeInviteId.value =
|
|
596
|
+
revokeInviteId.value = "";
|
|
595
597
|
}
|
|
596
598
|
}
|
|
597
599
|
|
|
@@ -603,8 +605,8 @@ async function submitMemberRoleUpdate(member, roleSid) {
|
|
|
603
605
|
membersFeedback.clear();
|
|
604
606
|
|
|
605
607
|
try {
|
|
606
|
-
const memberUserId =
|
|
607
|
-
if (!
|
|
608
|
+
const memberUserId = normalizeRecordId(member?.userId, { fallback: null });
|
|
609
|
+
if (!memberUserId) {
|
|
608
610
|
throw new Error("Member user id is invalid.");
|
|
609
611
|
}
|
|
610
612
|
|
|
@@ -630,12 +632,12 @@ async function submitRemoveMember(member) {
|
|
|
630
632
|
membersFeedback.clear();
|
|
631
633
|
|
|
632
634
|
try {
|
|
633
|
-
const memberUserId =
|
|
634
|
-
if (!
|
|
635
|
+
const memberUserId = normalizeRecordId(member?.userId, { fallback: null });
|
|
636
|
+
if (!memberUserId) {
|
|
635
637
|
throw new Error("Member user id is invalid.");
|
|
636
638
|
}
|
|
637
639
|
|
|
638
|
-
removeMemberUserId.value = memberUserId;
|
|
640
|
+
removeMemberUserId.value = normalizeRecordId(memberUserId, { fallback: "" });
|
|
639
641
|
await memberRemoveCommand.run({
|
|
640
642
|
memberUserId
|
|
641
643
|
});
|
|
@@ -647,7 +649,7 @@ async function submitRemoveMember(member) {
|
|
|
647
649
|
} catch (error) {
|
|
648
650
|
membersFeedback.error(error, "Unable to remove member.");
|
|
649
651
|
} finally {
|
|
650
|
-
removeMemberUserId.value =
|
|
652
|
+
removeMemberUserId.value = "";
|
|
651
653
|
}
|
|
652
654
|
}
|
|
653
655
|
</script>
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
normalizeReturnToPath as normalizeSharedReturnToPath,
|
|
4
4
|
resolveAllowedOriginsFromPlacementContext
|
|
5
5
|
} from "@jskit-ai/kernel/shared/support";
|
|
6
|
+
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
6
7
|
import { normalizeRecord } from "../../support/runtimeNormalization.js";
|
|
7
8
|
|
|
8
9
|
function normalizeReturnToPath(value, { fallback = "/", accountSettingsPath = "/account", allowedOrigins = [] } = {}) {
|
|
@@ -27,9 +28,9 @@ function normalizePendingInvite(entry) {
|
|
|
27
28
|
return null;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
const id =
|
|
31
|
-
const workspaceId =
|
|
32
|
-
if (!
|
|
31
|
+
const id = normalizeRecordId(entry.id, { fallback: null });
|
|
32
|
+
const workspaceId = normalizeRecordId(entry.workspaceId, { fallback: null });
|
|
33
|
+
if (!id || !workspaceId) {
|
|
33
34
|
return null;
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
2
|
+
|
|
1
3
|
function buildBootstrapApiPath(workspaceSlug = "") {
|
|
2
4
|
const normalizedWorkspaceSlug = String(workspaceSlug || "").trim();
|
|
3
5
|
if (!normalizedWorkspaceSlug) {
|
|
@@ -15,9 +17,9 @@ function normalizeWorkspaceEntry(entry) {
|
|
|
15
17
|
return null;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
const id =
|
|
20
|
+
const id = normalizeRecordId(entry.id, { fallback: null });
|
|
19
21
|
const slug = String(entry.slug || "").trim();
|
|
20
|
-
if (!
|
|
22
|
+
if (!id || !slug) {
|
|
21
23
|
return null;
|
|
22
24
|
}
|
|
23
25
|
|
|
@@ -69,8 +71,8 @@ function resolvePlacementUserFromBootstrapPayload(payload = {}, currentUser = nu
|
|
|
69
71
|
const fallbackUser = currentUser && typeof currentUser === "object" ? currentUser : {};
|
|
70
72
|
const nextUser = {};
|
|
71
73
|
|
|
72
|
-
const userId =
|
|
73
|
-
if (
|
|
74
|
+
const userId = normalizeRecordId(session.userId || fallbackUser.id, { fallback: null });
|
|
75
|
+
if (userId) {
|
|
74
76
|
nextUser.id = userId;
|
|
75
77
|
}
|
|
76
78
|
|
package/test/bootstrap.test.js
CHANGED
|
@@ -17,7 +17,7 @@ test("resolvePlacementUserFromBootstrapPayload maps profile fields used by place
|
|
|
17
17
|
const user = resolvePlacementUserFromBootstrapPayload({
|
|
18
18
|
session: {
|
|
19
19
|
authenticated: true,
|
|
20
|
-
userId: 42
|
|
20
|
+
userId: "42"
|
|
21
21
|
},
|
|
22
22
|
profile: {
|
|
23
23
|
displayName: "Ada Lovelace",
|
|
@@ -29,7 +29,7 @@ test("resolvePlacementUserFromBootstrapPayload maps profile fields used by place
|
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
assert.deepEqual(user, {
|
|
32
|
-
id: 42,
|
|
32
|
+
id: "42",
|
|
33
33
|
displayName: "Ada Lovelace",
|
|
34
34
|
name: "Ada Lovelace",
|
|
35
35
|
email: "ada@example.com",
|
|
@@ -245,7 +245,7 @@ test("bootstrap placement runtime writes user/workspace/permissions into placeme
|
|
|
245
245
|
return {
|
|
246
246
|
session: {
|
|
247
247
|
authenticated: true,
|
|
248
|
-
userId: 7
|
|
248
|
+
userId: "7"
|
|
249
249
|
},
|
|
250
250
|
profile: {
|
|
251
251
|
displayName: "Ada Lovelace",
|
|
@@ -260,10 +260,10 @@ test("bootstrap placement runtime writes user/workspace/permissions into placeme
|
|
|
260
260
|
}
|
|
261
261
|
},
|
|
262
262
|
pendingInvites: [
|
|
263
|
-
{ id: 1, workspaceId: 1, token: "a" },
|
|
264
|
-
{ id: 2, workspaceId: 2, token: "b" }
|
|
263
|
+
{ id: "1", workspaceId: "1", token: "a" },
|
|
264
|
+
{ id: "2", workspaceId: "2", token: "b" }
|
|
265
265
|
],
|
|
266
|
-
workspaces: [{ id: 1, slug: "acme", name: "Acme Workspace" }],
|
|
266
|
+
workspaces: [{ id: "1", slug: "acme", name: "Acme Workspace" }],
|
|
267
267
|
permissions: ["workspace.settings.view"]
|
|
268
268
|
};
|
|
269
269
|
}
|
|
@@ -280,7 +280,7 @@ test("bootstrap placement runtime writes user/workspace/permissions into placeme
|
|
|
280
280
|
assert.equal(runtime.getWorkspaceBootstrapStatus("acme"), WORKSPACE_BOOTSTRAP_STATUS_RESOLVED);
|
|
281
281
|
assert.equal(context.workspaceBootstrapStatuses?.acme, WORKSPACE_BOOTSTRAP_STATUS_RESOLVED);
|
|
282
282
|
assert.deepEqual(context.user, {
|
|
283
|
-
id: 7,
|
|
283
|
+
id: "7",
|
|
284
284
|
displayName: "Ada Lovelace",
|
|
285
285
|
name: "Ada Lovelace",
|
|
286
286
|
email: "ada@example.com",
|
|
@@ -305,7 +305,7 @@ test("bootstrap placement runtime resolves workspace slug from pathname when sur
|
|
|
305
305
|
return {
|
|
306
306
|
session: {
|
|
307
307
|
authenticated: true,
|
|
308
|
-
userId: 1
|
|
308
|
+
userId: "1"
|
|
309
309
|
},
|
|
310
310
|
profile: {
|
|
311
311
|
displayName: "User",
|
|
@@ -314,7 +314,7 @@ test("bootstrap placement runtime resolves workspace slug from pathname when sur
|
|
|
314
314
|
effectiveUrl: ""
|
|
315
315
|
}
|
|
316
316
|
},
|
|
317
|
-
workspaces: [{ id: 1, slug: "acme", name: "Acme Workspace" }],
|
|
317
|
+
workspaces: [{ id: "1", slug: "acme", name: "Acme Workspace" }],
|
|
318
318
|
permissions: ["workspace.settings.view"]
|
|
319
319
|
};
|
|
320
320
|
}
|
|
@@ -348,7 +348,7 @@ test("bootstrap placement runtime does not mutate placement auth context", async
|
|
|
348
348
|
return {
|
|
349
349
|
session: {
|
|
350
350
|
authenticated: true,
|
|
351
|
-
userId: 9
|
|
351
|
+
userId: "9"
|
|
352
352
|
},
|
|
353
353
|
profile: {
|
|
354
354
|
displayName: "User",
|
|
@@ -357,7 +357,7 @@ test("bootstrap placement runtime does not mutate placement auth context", async
|
|
|
357
357
|
effectiveUrl: ""
|
|
358
358
|
}
|
|
359
359
|
},
|
|
360
|
-
workspaces: [{ id: 1, slug: "acme", name: "Workspace" }],
|
|
360
|
+
workspaces: [{ id: "1", slug: "acme", name: "Workspace" }],
|
|
361
361
|
permissions: []
|
|
362
362
|
};
|
|
363
363
|
}
|
|
@@ -387,7 +387,7 @@ test("bootstrap placement runtime refetches on route changes and users.bootstrap
|
|
|
387
387
|
return {
|
|
388
388
|
session: {
|
|
389
389
|
authenticated: true,
|
|
390
|
-
userId: 1
|
|
390
|
+
userId: "1"
|
|
391
391
|
},
|
|
392
392
|
profile: {
|
|
393
393
|
displayName: "User",
|
|
@@ -396,7 +396,7 @@ test("bootstrap placement runtime refetches on route changes and users.bootstrap
|
|
|
396
396
|
effectiveUrl: ""
|
|
397
397
|
}
|
|
398
398
|
},
|
|
399
|
-
workspaces: [{ id: 1, slug: workspaceSlug || "acme", name: "Workspace" }],
|
|
399
|
+
workspaces: [{ id: "1", slug: workspaceSlug || "acme", name: "Workspace" }],
|
|
400
400
|
permissions: []
|
|
401
401
|
};
|
|
402
402
|
}
|
|
@@ -436,7 +436,7 @@ test("bootstrap placement runtime refetches when auth context changes", async ()
|
|
|
436
436
|
return {
|
|
437
437
|
session: {
|
|
438
438
|
authenticated: true,
|
|
439
|
-
userId: 1
|
|
439
|
+
userId: "1"
|
|
440
440
|
},
|
|
441
441
|
profile: {
|
|
442
442
|
displayName: "User",
|
|
@@ -445,7 +445,7 @@ test("bootstrap placement runtime refetches when auth context changes", async ()
|
|
|
445
445
|
effectiveUrl: ""
|
|
446
446
|
}
|
|
447
447
|
},
|
|
448
|
-
workspaces: [{ id: 1, slug: workspaceSlug || "acme", name: "Workspace" }],
|
|
448
|
+
workspaces: [{ id: "1", slug: workspaceSlug || "acme", name: "Workspace" }],
|
|
449
449
|
permissions: []
|
|
450
450
|
};
|
|
451
451
|
}
|
|
@@ -535,7 +535,7 @@ test("bootstrap placement runtime reapplies theme when bootstrap payload changes
|
|
|
535
535
|
return {
|
|
536
536
|
session: {
|
|
537
537
|
authenticated: true,
|
|
538
|
-
userId: 1
|
|
538
|
+
userId: "1"
|
|
539
539
|
},
|
|
540
540
|
profile: {
|
|
541
541
|
displayName: "User",
|
|
@@ -547,7 +547,7 @@ test("bootstrap placement runtime reapplies theme when bootstrap payload changes
|
|
|
547
547
|
userSettings: {
|
|
548
548
|
theme: fetchCount === 1 ? "dark" : "light"
|
|
549
549
|
},
|
|
550
|
-
workspaces: [{ id: 1, slug: workspaceSlug || "acme", name: "Workspace" }],
|
|
550
|
+
workspaces: [{ id: "1", slug: workspaceSlug || "acme", name: "Workspace" }],
|
|
551
551
|
permissions: []
|
|
552
552
|
};
|
|
553
553
|
}
|
|
@@ -575,7 +575,7 @@ test("bootstrap placement runtime applies workspace palette via Vuetify workspac
|
|
|
575
575
|
return {
|
|
576
576
|
session: {
|
|
577
577
|
authenticated: true,
|
|
578
|
-
userId: 1
|
|
578
|
+
userId: "1"
|
|
579
579
|
},
|
|
580
580
|
workspaceSettings: {
|
|
581
581
|
lightPrimaryColor: "#CC3344",
|
|
@@ -589,7 +589,7 @@ test("bootstrap placement runtime applies workspace palette via Vuetify workspac
|
|
|
589
589
|
},
|
|
590
590
|
workspaces: [
|
|
591
591
|
{
|
|
592
|
-
id: 1,
|
|
592
|
+
id: "1",
|
|
593
593
|
slug: "acme",
|
|
594
594
|
name: "Acme Workspace"
|
|
595
595
|
}
|
|
@@ -630,8 +630,8 @@ test("bootstrap placement runtime marks workspace slug as not_found and clears w
|
|
|
630
630
|
const placementRuntime = createPlacementRuntimeStub();
|
|
631
631
|
placementRuntime.setContext(
|
|
632
632
|
{
|
|
633
|
-
workspace: { id: 1, slug: "acme", name: "Acme Workspace" },
|
|
634
|
-
workspaces: [{ id: 1, slug: "acme", name: "Acme Workspace" }],
|
|
633
|
+
workspace: { id: "1", slug: "acme", name: "Acme Workspace" },
|
|
634
|
+
workspaces: [{ id: "1", slug: "acme", name: "Acme Workspace" }],
|
|
635
635
|
permissions: ["workspace.settings.view"]
|
|
636
636
|
},
|
|
637
637
|
{ source: "test.seed" }
|
|
@@ -680,7 +680,7 @@ test("bootstrap placement runtime updates status per workspace slug across route
|
|
|
680
680
|
return {
|
|
681
681
|
session: {
|
|
682
682
|
authenticated: true,
|
|
683
|
-
userId: 1
|
|
683
|
+
userId: "1"
|
|
684
684
|
},
|
|
685
685
|
profile: {
|
|
686
686
|
displayName: "User",
|
|
@@ -689,7 +689,7 @@ test("bootstrap placement runtime updates status per workspace slug across route
|
|
|
689
689
|
effectiveUrl: ""
|
|
690
690
|
}
|
|
691
691
|
},
|
|
692
|
-
workspaces: [{ id: 1, slug: workspaceSlug || "acme", name: "Workspace" }],
|
|
692
|
+
workspaces: [{ id: "1", slug: workspaceSlug || "acme", name: "Workspace" }],
|
|
693
693
|
permissions: []
|
|
694
694
|
};
|
|
695
695
|
}
|
|
@@ -721,7 +721,7 @@ test("bootstrap placement runtime uses requestedWorkspace status and keeps globa
|
|
|
721
721
|
return {
|
|
722
722
|
session: {
|
|
723
723
|
authenticated: true,
|
|
724
|
-
userId: 4
|
|
724
|
+
userId: "4"
|
|
725
725
|
},
|
|
726
726
|
profile: {
|
|
727
727
|
displayName: "Chiara",
|
|
@@ -730,7 +730,7 @@ test("bootstrap placement runtime uses requestedWorkspace status and keeps globa
|
|
|
730
730
|
effectiveUrl: ""
|
|
731
731
|
}
|
|
732
732
|
},
|
|
733
|
-
workspaces: [{ id: 3, slug: "chiaramobily", name: "Chiara Workspace" }],
|
|
733
|
+
workspaces: [{ id: "3", slug: "chiaramobily", name: "Chiara Workspace" }],
|
|
734
734
|
requestedWorkspace: {
|
|
735
735
|
slug: "tonymobily",
|
|
736
736
|
status: "forbidden"
|
|
@@ -763,7 +763,7 @@ test("bootstrap placement runtime uses requestedWorkspace=not_found without forc
|
|
|
763
763
|
return {
|
|
764
764
|
session: {
|
|
765
765
|
authenticated: true,
|
|
766
|
-
userId: 1
|
|
766
|
+
userId: "1"
|
|
767
767
|
},
|
|
768
768
|
profile: {
|
|
769
769
|
displayName: "User",
|
|
@@ -772,7 +772,7 @@ test("bootstrap placement runtime uses requestedWorkspace=not_found without forc
|
|
|
772
772
|
effectiveUrl: ""
|
|
773
773
|
}
|
|
774
774
|
},
|
|
775
|
-
workspaces: [{ id: 1, slug: "acme", name: "Acme Workspace" }],
|
|
775
|
+
workspaces: [{ id: "1", slug: "acme", name: "Acme Workspace" }],
|
|
776
776
|
requestedWorkspace: {
|
|
777
777
|
slug: "missing",
|
|
778
778
|
status: "not_found"
|
|
@@ -811,9 +811,9 @@ test("bootstrap placement runtime guard wrapper preserves delegated deny outcome
|
|
|
811
811
|
return {
|
|
812
812
|
session: {
|
|
813
813
|
authenticated: true,
|
|
814
|
-
userId: 1
|
|
814
|
+
userId: "1"
|
|
815
815
|
},
|
|
816
|
-
workspaces: [{ id: 1, slug: "acme", name: "Acme" }],
|
|
816
|
+
workspaces: [{ id: "1", slug: "acme", name: "Acme" }],
|
|
817
817
|
permissions: []
|
|
818
818
|
};
|
|
819
819
|
}
|
|
@@ -854,7 +854,7 @@ test("bootstrap placement runtime guard wrapper blocks forbidden workspace route
|
|
|
854
854
|
return {
|
|
855
855
|
session: {
|
|
856
856
|
authenticated: true,
|
|
857
|
-
userId: 1
|
|
857
|
+
userId: "1"
|
|
858
858
|
},
|
|
859
859
|
workspaces: [],
|
|
860
860
|
permissions: []
|
|
@@ -1032,7 +1032,7 @@ test("bootstrap placement runtime enforces surface access policies after bootstr
|
|
|
1032
1032
|
return {
|
|
1033
1033
|
session: {
|
|
1034
1034
|
authenticated: true,
|
|
1035
|
-
userId: 1
|
|
1035
|
+
userId: "1"
|
|
1036
1036
|
},
|
|
1037
1037
|
workspaces: [],
|
|
1038
1038
|
permissions: [],
|
|
@@ -1059,9 +1059,9 @@ test("bootstrap placement runtime captures guard evaluator assignments after ini
|
|
|
1059
1059
|
return {
|
|
1060
1060
|
session: {
|
|
1061
1061
|
authenticated: true,
|
|
1062
|
-
userId: 1
|
|
1062
|
+
userId: "1"
|
|
1063
1063
|
},
|
|
1064
|
-
workspaces: [{ id: 1, slug: "acme", name: "Acme" }],
|
|
1064
|
+
workspaces: [{ id: "1", slug: "acme", name: "Acme" }],
|
|
1065
1065
|
permissions: []
|
|
1066
1066
|
};
|
|
1067
1067
|
}
|