@jskit-ai/users-core 0.1.47 → 0.1.49
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 +9 -46
- package/package.json +8 -19
- package/src/server/UsersCoreServiceProvider.js +0 -4
- package/src/server/common/registerCommonRepositories.js +0 -5
- package/src/server/common/services/authProfileSyncService.js +28 -7
- package/src/server/common/support/realtimeServiceEvents.js +1 -59
- package/src/server/profileSyncLifecycleContributorRegistry.js +56 -0
- package/src/server/registerUsersBootstrap.js +1 -3
- package/src/server/registerUsersCore.js +2 -14
- package/src/server/usersBootstrapContributor.js +10 -85
- package/src/shared/index.js +2 -99
- package/src/shared/settings.js +1 -119
- package/templates/migrations/users_core_generic_initial.cjs +0 -16
- package/test/authProfileSyncService.test.js +19 -10
- package/test/registerServiceRealtimeEvents.test.js +0 -94
- package/test/registerUsersCore.test.js +6 -19
- package/test/repositoryContracts.test.js +1 -11
- package/test/resourcesCanonical.test.js +1 -19
- package/test/settingsFieldRegistriesSingleton.test.js +0 -10
- package/test/usersBootstrapContributor.test.js +20 -38
- package/test/usersRouteRequestInputValidator.test.js +2 -43
- package/test/usersRouteResources.test.js +2 -20
- package/test-support/registerDefaultSettingsFields.js +0 -1
- package/src/server/UsersWorkspacesServiceProvider.js +0 -44
- package/src/server/common/contributors/workspaceActionContextContributor.js +0 -88
- package/src/server/common/contributors/workspaceAuthPolicyContextResolver.js +0 -34
- package/src/server/common/contributors/workspaceRouteVisibilityResolver.js +0 -78
- package/src/server/common/formatters/workspaceFormatter.js +0 -53
- package/src/server/common/repositories/workspaceInvitesRepository.js +0 -208
- package/src/server/common/repositories/workspaceMembershipsRepository.js +0 -190
- package/src/server/common/repositories/workspacesRepository.js +0 -202
- package/src/server/common/services/workspaceContextService.js +0 -281
- package/src/server/common/support/workspaceRoutePaths.js +0 -17
- package/src/server/common/validators/routeParamsValidator.js +0 -62
- package/src/server/consoleSettings/bootConsoleSettingsRoutes.js +0 -63
- package/src/server/consoleSettings/consoleService.js +0 -36
- package/src/server/consoleSettings/consoleSettingsActions.js +0 -55
- package/src/server/consoleSettings/consoleSettingsRepository.js +0 -115
- package/src/server/consoleSettings/consoleSettingsService.js +0 -40
- package/src/server/consoleSettings/registerConsoleSettings.js +0 -56
- package/src/server/registerWorkspaceBootstrap.js +0 -27
- package/src/server/registerWorkspaceCore.js +0 -73
- package/src/server/registerWorkspaceRepositories.js +0 -26
- package/src/server/support/resolveWorkspace.js +0 -16
- package/src/server/support/workspaceActionSurfaces.js +0 -135
- package/src/server/support/workspaceInvitationsPolicy.js +0 -45
- package/src/server/support/workspaceRouteInput.js +0 -22
- package/src/server/workspaceBootstrapContributor.js +0 -211
- package/src/server/workspaceDirectory/bootWorkspaceDirectoryRoutes.js +0 -133
- package/src/server/workspaceDirectory/registerWorkspaceDirectory.js +0 -19
- package/src/server/workspaceDirectory/workspaceDirectoryActions.js +0 -133
- package/src/server/workspaceMembers/bootWorkspaceMembers.js +0 -236
- package/src/server/workspaceMembers/registerWorkspaceMembers.js +0 -108
- package/src/server/workspaceMembers/workspaceMembersActions.js +0 -186
- package/src/server/workspaceMembers/workspaceMembersService.js +0 -222
- package/src/server/workspacePendingInvitations/bootWorkspacePendingInvitations.js +0 -62
- package/src/server/workspacePendingInvitations/registerWorkspacePendingInvitations.js +0 -119
- package/src/server/workspacePendingInvitations/workspacePendingInvitationsActions.js +0 -74
- package/src/server/workspacePendingInvitations/workspacePendingInvitationsService.js +0 -138
- package/src/server/workspaceSettings/bootWorkspaceSettings.js +0 -76
- package/src/server/workspaceSettings/registerWorkspaceSettings.js +0 -62
- package/src/server/workspaceSettings/workspaceSettingsActions.js +0 -72
- package/src/server/workspaceSettings/workspaceSettingsRepository.js +0 -154
- package/src/server/workspaceSettings/workspaceSettingsService.js +0 -66
- package/src/shared/resources/consoleSettingsFields.js +0 -54
- package/src/shared/resources/consoleSettingsResource.js +0 -119
- package/src/shared/resources/workspaceMembersResource.js +0 -354
- package/src/shared/resources/workspacePendingInvitationsResource.js +0 -82
- package/src/shared/resources/workspaceResource.js +0 -176
- package/src/shared/resources/workspaceSettingsFields.js +0 -59
- package/src/shared/resources/workspaceSettingsResource.js +0 -169
- package/src/shared/roles.js +0 -161
- package/src/shared/support/usersApiPaths.js +0 -43
- package/src/shared/support/usersVisibility.js +0 -42
- package/src/shared/support/workspacePathModel.js +0 -145
- package/src/shared/tenancyMode.js +0 -35
- package/src/shared/tenancyProfile.js +0 -73
- package/templates/migrations/users_core_console_owner.cjs +0 -37
- package/templates/packages/main/src/shared/resources/consoleSettingsFields.js +0 -11
- package/test/consoleService.test.js +0 -57
- package/test/consoleSettingsService.test.js +0 -86
- package/test/registerWorkspaceDirectory.test.js +0 -31
- package/test/registerWorkspaceSettings.test.js +0 -40
- package/test/roles.test.js +0 -159
- package/test/tenancyProfile.test.js +0 -67
- package/test/usersApiPaths.test.js +0 -49
- package/test/usersRouteValidators.test.js +0 -49
- package/test/usersVisibility.test.js +0 -27
- package/test/workspaceActionContextContributor.test.js +0 -344
- package/test/workspaceActionSurfaces.test.js +0 -105
- package/test/workspaceAuthPolicyContextResolver.test.js +0 -119
- package/test/workspaceBootstrapContributor.test.js +0 -154
- package/test/workspaceInvitationsPolicy.test.js +0 -71
- package/test/workspaceInvitesRepository.test.js +0 -111
- package/test/workspaceMembersService.test.js +0 -398
- package/test/workspacePathModel.test.js +0 -93
- package/test/workspacePendingInvitationsResource.test.js +0 -38
- package/test/workspacePendingInvitationsService.test.js +0 -151
- package/test/workspaceRouteVisibilityResolver.test.js +0 -83
- package/test/workspaceService.test.js +0 -546
- package/test/workspaceSettingsActions.test.js +0 -52
- package/test/workspaceSettingsRepository.test.js +0 -202
- package/test/workspaceSettingsResource.test.js +0 -169
- package/test/workspaceSettingsService.test.js +0 -140
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import test from "node:test";
|
|
3
3
|
import { createUsersBootstrapContributor } from "../src/server/usersBootstrapContributor.js";
|
|
4
|
-
import {
|
|
5
|
-
TENANCY_MODE_PERSONAL,
|
|
6
|
-
WORKSPACE_SLUG_POLICY_IMMUTABLE_USERNAME
|
|
7
|
-
} from "../src/shared/tenancyProfile.js";
|
|
8
4
|
|
|
9
5
|
function createAuthenticatedProfile(overrides = {}) {
|
|
10
6
|
return {
|
|
@@ -33,9 +29,8 @@ function createUserSettings() {
|
|
|
33
29
|
};
|
|
34
30
|
}
|
|
35
31
|
|
|
36
|
-
test("users bootstrap contributor
|
|
32
|
+
test("users bootstrap contributor exposes the generic authenticated bootstrap payload", async () => {
|
|
37
33
|
const profile = createAuthenticatedProfile({ id: "12" });
|
|
38
|
-
const consoleOwnerSeeds = [];
|
|
39
34
|
const writtenSessions = [];
|
|
40
35
|
const contributor = createUsersBootstrapContributor({
|
|
41
36
|
usersRepository: {
|
|
@@ -60,12 +55,6 @@ test("users bootstrap contributor seeds the initial console owner and exposes ge
|
|
|
60
55
|
defaultProvider: "google"
|
|
61
56
|
};
|
|
62
57
|
}
|
|
63
|
-
},
|
|
64
|
-
consoleService: {
|
|
65
|
-
async ensureInitialConsoleMember(userId) {
|
|
66
|
-
consoleOwnerSeeds.push(Number(userId));
|
|
67
|
-
return String(userId || "");
|
|
68
|
-
}
|
|
69
58
|
}
|
|
70
59
|
});
|
|
71
60
|
|
|
@@ -82,10 +71,14 @@ test("users bootstrap contributor seeds the initial console owner and exposes ge
|
|
|
82
71
|
};
|
|
83
72
|
}
|
|
84
73
|
},
|
|
74
|
+
payload: {
|
|
75
|
+
surfaceAccess: {
|
|
76
|
+
consoleowner: true
|
|
77
|
+
}
|
|
78
|
+
},
|
|
85
79
|
reply
|
|
86
80
|
});
|
|
87
|
-
|
|
88
|
-
assert.deepEqual(consoleOwnerSeeds, [12]);
|
|
81
|
+
assert.equal(contributor.order, 100);
|
|
89
82
|
assert.equal(writtenSessions.length, 1);
|
|
90
83
|
assert.equal(writtenSessions[0].reply, reply);
|
|
91
84
|
assert.deepEqual(writtenSessions[0].session, {
|
|
@@ -93,8 +86,10 @@ test("users bootstrap contributor seeds the initial console owner and exposes ge
|
|
|
93
86
|
});
|
|
94
87
|
assert.equal(payload.session.authenticated, true);
|
|
95
88
|
assert.equal(payload.session.userId, "12");
|
|
96
|
-
assert.
|
|
97
|
-
|
|
89
|
+
assert.deepEqual(payload.surfaceAccess, {
|
|
90
|
+
consoleowner: true
|
|
91
|
+
});
|
|
92
|
+
assert.equal(payload.app.features.assistantEnabled, false);
|
|
98
93
|
assert.deepEqual(payload.session.oauthProviders, [
|
|
99
94
|
{
|
|
100
95
|
id: "google",
|
|
@@ -102,12 +97,11 @@ test("users bootstrap contributor seeds the initial console owner and exposes ge
|
|
|
102
97
|
}
|
|
103
98
|
]);
|
|
104
99
|
assert.equal(payload.session.oauthDefaultProvider, "google");
|
|
105
|
-
assert.deepEqual(payload.workspaces, []);
|
|
106
100
|
assert.deepEqual(payload.userSettings, {});
|
|
107
101
|
assert.equal(payload.requestMeta.hasRequest, true);
|
|
108
102
|
});
|
|
109
103
|
|
|
110
|
-
test("users bootstrap contributor emits
|
|
104
|
+
test("users bootstrap contributor emits anonymous bootstrap payload without workspace fields", async () => {
|
|
111
105
|
const contributor = createUsersBootstrapContributor({
|
|
112
106
|
usersRepository: {
|
|
113
107
|
async findById() {
|
|
@@ -119,15 +113,6 @@ test("users bootstrap contributor emits canonical tenancy profile for anonymous
|
|
|
119
113
|
return createUserSettings();
|
|
120
114
|
}
|
|
121
115
|
},
|
|
122
|
-
tenancyProfile: {
|
|
123
|
-
mode: TENANCY_MODE_PERSONAL,
|
|
124
|
-
workspace: {
|
|
125
|
-
enabled: true,
|
|
126
|
-
autoProvision: true,
|
|
127
|
-
allowSelfCreate: false,
|
|
128
|
-
slugPolicy: WORKSPACE_SLUG_POLICY_IMMUTABLE_USERNAME
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
116
|
appConfig: {
|
|
132
117
|
tenancyMode: "none"
|
|
133
118
|
},
|
|
@@ -149,24 +134,21 @@ test("users bootstrap contributor emits canonical tenancy profile for anonymous
|
|
|
149
134
|
};
|
|
150
135
|
}
|
|
151
136
|
},
|
|
137
|
+
payload: {
|
|
138
|
+
surfaceAccess: {
|
|
139
|
+
consoleowner: false
|
|
140
|
+
}
|
|
141
|
+
},
|
|
152
142
|
reply: {}
|
|
153
143
|
});
|
|
154
144
|
|
|
155
|
-
assert.deepEqual(payload.tenancy, {
|
|
156
|
-
mode: TENANCY_MODE_PERSONAL,
|
|
157
|
-
workspace: {
|
|
158
|
-
enabled: true,
|
|
159
|
-
autoProvision: true,
|
|
160
|
-
allowSelfCreate: false,
|
|
161
|
-
slugPolicy: WORKSPACE_SLUG_POLICY_IMMUTABLE_USERNAME
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
145
|
assert.deepEqual(payload.session, {
|
|
165
146
|
authenticated: false,
|
|
166
147
|
oauthProviders: [],
|
|
167
148
|
oauthDefaultProvider: null
|
|
168
149
|
});
|
|
169
|
-
assert.deepEqual(payload.
|
|
170
|
-
|
|
150
|
+
assert.deepEqual(payload.surfaceAccess, {
|
|
151
|
+
consoleowner: false
|
|
152
|
+
});
|
|
171
153
|
assert.equal(payload.userSettings, null);
|
|
172
154
|
});
|
|
@@ -27,8 +27,7 @@ function findRoute(routes, { method, path }) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
async function registerRoutes({
|
|
30
|
-
authService = {}
|
|
31
|
-
consoleService = null
|
|
30
|
+
authService = {}
|
|
32
31
|
} = {}) {
|
|
33
32
|
const registeredRoutes = [];
|
|
34
33
|
const router = {
|
|
@@ -59,10 +58,6 @@ async function registerRoutes({
|
|
|
59
58
|
["actionExecutor", {}]
|
|
60
59
|
]);
|
|
61
60
|
|
|
62
|
-
if (consoleService) {
|
|
63
|
-
bindings.set("consoleService", consoleService);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
61
|
const app = {
|
|
67
62
|
has(token) {
|
|
68
63
|
return bindings.has(token);
|
|
@@ -92,13 +87,11 @@ function createActionRequest({ input = {}, executeAction, file = null }) {
|
|
|
92
87
|
};
|
|
93
88
|
}
|
|
94
89
|
|
|
95
|
-
test("users-core boot mounts account
|
|
90
|
+
test("users-core boot mounts account routes without workspace routes", async () => {
|
|
96
91
|
const routes = await registerRoutes();
|
|
97
92
|
|
|
98
93
|
assert.equal(findRoute(routes, { method: "GET", path: "/api/settings" })?.path, "/api/settings");
|
|
99
94
|
assert.equal(findRoute(routes, { method: "PATCH", path: "/api/settings/profile" })?.path, "/api/settings/profile");
|
|
100
|
-
assert.equal(findRoute(routes, { method: "GET", path: "/api/console/settings" })?.path, "/api/console/settings");
|
|
101
|
-
assert.equal(findRoute(routes, { method: "PATCH", path: "/api/console/settings" })?.path, "/api/console/settings");
|
|
102
95
|
assert.equal(findRoute(routes, { method: "GET", path: "/api/workspaces" }), null);
|
|
103
96
|
assert.equal(findRoute(routes, { method: "GET", path: "/api/w/:workspaceSlug/settings" }), null);
|
|
104
97
|
});
|
|
@@ -206,37 +199,3 @@ test("account route handlers build action input from request.input", async () =>
|
|
|
206
199
|
assert.deepEqual(calls[6].input, { provider: "github" });
|
|
207
200
|
assert.equal(calls[7].actionId, "settings.security.sessions.logout_others");
|
|
208
201
|
});
|
|
209
|
-
|
|
210
|
-
test("console settings route handlers use request.input payloads", async () => {
|
|
211
|
-
const routes = await registerRoutes();
|
|
212
|
-
const calls = [];
|
|
213
|
-
const executeAction = async (payload) => {
|
|
214
|
-
calls.push(payload);
|
|
215
|
-
return {
|
|
216
|
-
settings: {}
|
|
217
|
-
};
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
await findRoute(routes, { method: "GET", path: "/api/console/settings" }).handler(
|
|
221
|
-
createActionRequest({ executeAction }),
|
|
222
|
-
createReplyDouble()
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
await findRoute(routes, { method: "PATCH", path: "/api/console/settings" }).handler(
|
|
226
|
-
createActionRequest({
|
|
227
|
-
input: {
|
|
228
|
-
body: {}
|
|
229
|
-
},
|
|
230
|
-
executeAction
|
|
231
|
-
}),
|
|
232
|
-
createReplyDouble()
|
|
233
|
-
);
|
|
234
|
-
|
|
235
|
-
assert.equal(calls[0].actionId, "console.settings.read");
|
|
236
|
-
assert.deepEqual(calls[1], {
|
|
237
|
-
actionId: "console.settings.update",
|
|
238
|
-
input: {
|
|
239
|
-
payload: {}
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
});
|
|
@@ -5,12 +5,8 @@ import { existsSync } from "node:fs";
|
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { deriveResourceRequiredMetadata } from "@jskit-ai/kernel/_testable";
|
|
7
7
|
import "../test-support/registerDefaultSettingsFields.js";
|
|
8
|
-
import { consoleSettingsResource } from "../src/shared/resources/consoleSettingsResource.js";
|
|
9
8
|
import { userProfileResource } from "../src/shared/resources/userProfileResource.js";
|
|
10
9
|
import { userSettingsResource } from "../src/shared/resources/userSettingsResource.js";
|
|
11
|
-
import { workspaceMembersResource } from "../src/shared/resources/workspaceMembersResource.js";
|
|
12
|
-
import { workspaceResource } from "../src/shared/resources/workspaceResource.js";
|
|
13
|
-
import { workspaceSettingsResource } from "../src/shared/resources/workspaceSettingsResource.js";
|
|
14
10
|
|
|
15
11
|
function assertResourceShape(resource, label) {
|
|
16
12
|
assert.ok(resource, `${label} resource must exist.`);
|
|
@@ -47,13 +43,10 @@ function assertResourceShape(resource, label) {
|
|
|
47
43
|
assert.ok(Array.isArray(requiredMetadata.patch), `${label}.derivedRequired.patch must be an array.`);
|
|
48
44
|
}
|
|
49
45
|
|
|
50
|
-
test("workspace
|
|
46
|
+
test("workspace and account resources expose canonical validators", () => {
|
|
51
47
|
const resourcesByLabel = {
|
|
52
|
-
workspace: workspaceResource,
|
|
53
|
-
workspaceSettings: workspaceSettingsResource,
|
|
54
48
|
userProfile: userProfileResource,
|
|
55
|
-
userSettings: userSettingsResource
|
|
56
|
-
consoleSettings: consoleSettingsResource
|
|
49
|
+
userSettings: userSettingsResource
|
|
57
50
|
};
|
|
58
51
|
|
|
59
52
|
for (const [label, resource] of Object.entries(resourcesByLabel)) {
|
|
@@ -62,18 +55,7 @@ test("workspace/settings/console resources expose canonical validators", () => {
|
|
|
62
55
|
});
|
|
63
56
|
|
|
64
57
|
test("specialized settings and invite operations expose canonical validators", () => {
|
|
65
|
-
const workspaceMembersOperationSpecs = [
|
|
66
|
-
{ label: "workspaceMembers.rolesList", operation: workspaceMembersResource.operations.rolesList },
|
|
67
|
-
{ label: "workspaceMembers.membersList", operation: workspaceMembersResource.operations.membersList },
|
|
68
|
-
{ label: "workspaceMembers.updateMemberRole", operation: workspaceMembersResource.operations.updateMemberRole },
|
|
69
|
-
{ label: "workspaceMembers.removeMember", operation: workspaceMembersResource.operations.removeMember },
|
|
70
|
-
{ label: "workspaceMembers.invitesList", operation: workspaceMembersResource.operations.invitesList },
|
|
71
|
-
{ label: "workspaceMembers.createInvite", operation: workspaceMembersResource.operations.createInvite },
|
|
72
|
-
{ label: "workspaceMembers.revokeInvite", operation: workspaceMembersResource.operations.revokeInvite },
|
|
73
|
-
{ label: "workspaceMembers.redeemInvite", operation: workspaceMembersResource.operations.redeemInvite }
|
|
74
|
-
];
|
|
75
58
|
const operationSpecs = [
|
|
76
|
-
...workspaceMembersOperationSpecs,
|
|
77
59
|
{ label: "userProfile.avatarUpload", operation: userProfileResource.operations.avatarUpload },
|
|
78
60
|
{ label: "userProfile.avatarDelete", operation: userProfileResource.operations.avatarDelete },
|
|
79
61
|
{ label: "userSettings.passwordChange", operation: userSettingsResource.operations.passwordChange },
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { bootWorkspaceDirectoryRoutes } from "./workspaceDirectory/bootWorkspaceDirectoryRoutes.js";
|
|
2
|
-
import { registerWorkspaceDirectory } from "./workspaceDirectory/registerWorkspaceDirectory.js";
|
|
3
|
-
import {
|
|
4
|
-
registerWorkspacePendingInvitations
|
|
5
|
-
} from "./workspacePendingInvitations/registerWorkspacePendingInvitations.js";
|
|
6
|
-
import { bootWorkspacePendingInvitations } from "./workspacePendingInvitations/bootWorkspacePendingInvitations.js";
|
|
7
|
-
import { registerWorkspaceMembers } from "./workspaceMembers/registerWorkspaceMembers.js";
|
|
8
|
-
import { bootWorkspaceMembers } from "./workspaceMembers/bootWorkspaceMembers.js";
|
|
9
|
-
import { registerWorkspaceSettings } from "./workspaceSettings/registerWorkspaceSettings.js";
|
|
10
|
-
import { bootWorkspaceSettings } from "./workspaceSettings/bootWorkspaceSettings.js";
|
|
11
|
-
import { registerWorkspaceRepositories } from "./registerWorkspaceRepositories.js";
|
|
12
|
-
import { registerWorkspaceCore } from "./registerWorkspaceCore.js";
|
|
13
|
-
import { registerWorkspaceBootstrap } from "./registerWorkspaceBootstrap.js";
|
|
14
|
-
|
|
15
|
-
class UsersWorkspacesServiceProvider {
|
|
16
|
-
static id = "workspaces.core";
|
|
17
|
-
|
|
18
|
-
static dependsOn = ["users.core"];
|
|
19
|
-
|
|
20
|
-
register(app) {
|
|
21
|
-
registerWorkspaceRepositories(app);
|
|
22
|
-
registerWorkspaceCore(app);
|
|
23
|
-
registerWorkspaceBootstrap(app);
|
|
24
|
-
registerWorkspaceDirectory(app);
|
|
25
|
-
registerWorkspaceMembers(app);
|
|
26
|
-
registerWorkspaceSettings(app);
|
|
27
|
-
registerWorkspacePendingInvitations(app);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async boot(app) {
|
|
31
|
-
if (app.make("users.workspace.enabled") !== true) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
bootWorkspaceDirectoryRoutes(app);
|
|
36
|
-
if (app.make("users.workspace.invitations.enabled") === true) {
|
|
37
|
-
bootWorkspacePendingInvitations(app);
|
|
38
|
-
}
|
|
39
|
-
bootWorkspaceSettings(app);
|
|
40
|
-
bootWorkspaceMembers(app);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export { UsersWorkspacesServiceProvider };
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
normalizeObject,
|
|
3
|
-
requireServiceMethod
|
|
4
|
-
} from "@jskit-ai/kernel/shared/actions/actionContributorHelpers";
|
|
5
|
-
import { normalizeSurfaceId } from "@jskit-ai/kernel/shared/surface/registry";
|
|
6
|
-
import {
|
|
7
|
-
checkRouteVisibility,
|
|
8
|
-
USERS_ROUTE_VISIBILITY_PUBLIC,
|
|
9
|
-
USERS_ROUTE_VISIBILITY_WORKSPACE,
|
|
10
|
-
USERS_ROUTE_VISIBILITY_WORKSPACE_USER
|
|
11
|
-
} from "../../../shared/support/usersVisibility.js";
|
|
12
|
-
import { resolveActionUser } from "../support/resolveActionUser.js";
|
|
13
|
-
const WORKSPACE_VISIBILITY_ACTION_CONTEXT_SET = new Set([
|
|
14
|
-
USERS_ROUTE_VISIBILITY_WORKSPACE,
|
|
15
|
-
USERS_ROUTE_VISIBILITY_WORKSPACE_USER
|
|
16
|
-
]);
|
|
17
|
-
|
|
18
|
-
function normalizeWorkspaceSurfaceIds(surfaceIds = []) {
|
|
19
|
-
const source = Array.isArray(surfaceIds) ? surfaceIds : [];
|
|
20
|
-
const normalized = new Set();
|
|
21
|
-
|
|
22
|
-
for (const entry of source) {
|
|
23
|
-
const surfaceId = normalizeSurfaceId(entry);
|
|
24
|
-
if (!surfaceId) {
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
normalized.add(surfaceId);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return normalized;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function createWorkspaceActionContextContributor({ workspaceService, workspaceSurfaceIds = [] } = {}) {
|
|
34
|
-
const contributorId = "users.workspace.context";
|
|
35
|
-
const workspaceSurfaceIdSet = normalizeWorkspaceSurfaceIds(workspaceSurfaceIds);
|
|
36
|
-
|
|
37
|
-
requireServiceMethod(workspaceService, "resolveWorkspaceContextForUserBySlug", contributorId);
|
|
38
|
-
|
|
39
|
-
return Object.freeze({
|
|
40
|
-
contributorId,
|
|
41
|
-
async contribute({ definition = null, input, context, request } = {}) {
|
|
42
|
-
const payload = normalizeObject(input);
|
|
43
|
-
if (!Object.hasOwn(payload, "workspaceSlug")) {
|
|
44
|
-
return {};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const actionSurfaces = Array.isArray(definition?.surfaces) ? definition.surfaces : [];
|
|
48
|
-
const hasWorkspaceActionSurface = actionSurfaces.some((surfaceId) => workspaceSurfaceIdSet.has(surfaceId));
|
|
49
|
-
const routeSurfaceId = normalizeSurfaceId(request?.routeOptions?.config?.surface);
|
|
50
|
-
const hasWorkspaceSurface = workspaceSurfaceIdSet.has(routeSurfaceId);
|
|
51
|
-
const routeVisibilityInput =
|
|
52
|
-
request && request.routeOptions && request.routeOptions.config
|
|
53
|
-
? request.routeOptions.config.visibility
|
|
54
|
-
: USERS_ROUTE_VISIBILITY_PUBLIC;
|
|
55
|
-
const routeVisibility = checkRouteVisibility(routeVisibilityInput);
|
|
56
|
-
const hasWorkspaceRouteVisibility = WORKSPACE_VISIBILITY_ACTION_CONTEXT_SET.has(routeVisibility);
|
|
57
|
-
if (!hasWorkspaceActionSurface && !hasWorkspaceRouteVisibility && !hasWorkspaceSurface) {
|
|
58
|
-
return {};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const resolvedWorkspaceContext = await workspaceService.resolveWorkspaceContextForUserBySlug(
|
|
62
|
-
resolveActionUser(context, payload),
|
|
63
|
-
payload.workspaceSlug,
|
|
64
|
-
{ request }
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
const contribution = {
|
|
68
|
-
requestMeta: {
|
|
69
|
-
resolvedWorkspaceContext
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
if (!context?.workspace) {
|
|
74
|
-
contribution.workspace = resolvedWorkspaceContext.workspace;
|
|
75
|
-
}
|
|
76
|
-
if (!context?.membership) {
|
|
77
|
-
contribution.membership = resolvedWorkspaceContext.membership;
|
|
78
|
-
}
|
|
79
|
-
if (!Array.isArray(context?.permissions) || context.permissions.length < 1) {
|
|
80
|
-
contribution.permissions = resolvedWorkspaceContext.permissions;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return contribution;
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export { createWorkspaceActionContextContributor };
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
2
|
-
|
|
3
|
-
function createWorkspaceAuthPolicyContextResolver({ workspaceService } = {}) {
|
|
4
|
-
if (!workspaceService || typeof workspaceService.resolveWorkspaceContextForUserBySlug !== "function") {
|
|
5
|
-
throw new Error(
|
|
6
|
-
"workspace auth policy context resolver requires workspaceService.resolveWorkspaceContextForUserBySlug()."
|
|
7
|
-
);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return async function resolveWorkspaceAuthPolicyContext({ request, actor, meta } = {}) {
|
|
11
|
-
const contextPolicy = normalizeText(meta?.contextPolicy || "none").toLowerCase() || "none";
|
|
12
|
-
const permission = normalizeText(meta?.permission);
|
|
13
|
-
if (contextPolicy === "none" && !permission) {
|
|
14
|
-
return {};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const workspaceSlug = normalizeText(request?.params?.workspaceSlug).toLowerCase();
|
|
18
|
-
if (!workspaceSlug || !actor) {
|
|
19
|
-
return {};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const resolvedWorkspaceContext = await workspaceService.resolveWorkspaceContextForUserBySlug(actor, workspaceSlug, {
|
|
23
|
-
request
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
workspace: resolvedWorkspaceContext?.workspace || null,
|
|
28
|
-
membership: resolvedWorkspaceContext?.membership || null,
|
|
29
|
-
permissions: Array.isArray(resolvedWorkspaceContext?.permissions) ? resolvedWorkspaceContext.permissions : []
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export { createWorkspaceAuthPolicyContextResolver };
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { normalizeOpaqueId, normalizeRecordId, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
2
|
-
|
|
3
|
-
function buildVisibilityContribution({ visibility, scopeOwnerId = null, userId = null } = {}) {
|
|
4
|
-
const requiresActorScope = visibility === "workspace_user";
|
|
5
|
-
const contribution = {
|
|
6
|
-
scopeKind: requiresActorScope ? "workspace_user" : "workspace",
|
|
7
|
-
requiresActorScope
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
if (scopeOwnerId) {
|
|
11
|
-
contribution.scopeOwnerId = scopeOwnerId;
|
|
12
|
-
}
|
|
13
|
-
if (requiresActorScope && userId != null) {
|
|
14
|
-
contribution.userId = userId;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return contribution;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function createWorkspaceRouteVisibilityResolver({ workspaceService } = {}) {
|
|
21
|
-
if (!workspaceService || typeof workspaceService.resolveWorkspaceContextForUserBySlug !== "function") {
|
|
22
|
-
throw new Error("workspace route visibility resolver requires workspaceService.resolveWorkspaceContextForUserBySlug().");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return Object.freeze({
|
|
26
|
-
resolverId: "users.workspace.visibility",
|
|
27
|
-
async resolve({ visibility, context, request, input } = {}) {
|
|
28
|
-
if (visibility !== "workspace" && visibility !== "workspace_user") {
|
|
29
|
-
return {};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const actor = context?.actor || request?.user || null;
|
|
33
|
-
const userId = normalizeOpaqueId(actor?.id);
|
|
34
|
-
const workspace =
|
|
35
|
-
context?.workspace || context?.requestMeta?.resolvedWorkspaceContext?.workspace || request?.workspace || null;
|
|
36
|
-
const scopeOwnerId = normalizeRecordId(workspace?.id, { fallback: null });
|
|
37
|
-
if (!scopeOwnerId) {
|
|
38
|
-
const workspaceSlug = normalizeText(input?.workspaceSlug).toLowerCase();
|
|
39
|
-
|
|
40
|
-
if (!workspaceSlug || !actor) {
|
|
41
|
-
return visibility === "workspace_user"
|
|
42
|
-
? buildVisibilityContribution({
|
|
43
|
-
visibility,
|
|
44
|
-
userId
|
|
45
|
-
})
|
|
46
|
-
: {};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const resolvedWorkspaceContext = await workspaceService.resolveWorkspaceContextForUserBySlug(actor, workspaceSlug, {
|
|
50
|
-
request
|
|
51
|
-
});
|
|
52
|
-
const resolvedWorkspaceOwnerId = normalizeRecordId(resolvedWorkspaceContext?.workspace?.id, { fallback: null });
|
|
53
|
-
if (!resolvedWorkspaceOwnerId) {
|
|
54
|
-
return visibility === "workspace_user"
|
|
55
|
-
? buildVisibilityContribution({
|
|
56
|
-
visibility,
|
|
57
|
-
userId
|
|
58
|
-
})
|
|
59
|
-
: {};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return buildVisibilityContribution({
|
|
63
|
-
visibility,
|
|
64
|
-
scopeOwnerId: resolvedWorkspaceOwnerId,
|
|
65
|
-
userId
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return buildVisibilityContribution({
|
|
70
|
-
visibility,
|
|
71
|
-
scopeOwnerId,
|
|
72
|
-
userId
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export { createWorkspaceRouteVisibilityResolver };
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { resolveWorkspaceThemePalettes } from "../../../shared/settings.js";
|
|
2
|
-
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/actions/textNormalization";
|
|
3
|
-
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
4
|
-
|
|
5
|
-
function mapWorkspaceSummary(workspace, membership) {
|
|
6
|
-
return {
|
|
7
|
-
id: normalizeRecordId(workspace.id, { fallback: "" }),
|
|
8
|
-
slug: normalizeText(workspace.slug),
|
|
9
|
-
name: normalizeText(workspace.name),
|
|
10
|
-
avatarUrl: normalizeText(workspace.avatarUrl),
|
|
11
|
-
roleSid: normalizeLowerText(membership?.roleSid || "member") || "member",
|
|
12
|
-
isAccessible: normalizeLowerText(membership?.status || "active") === "active"
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function mapWorkspaceSettingsPublic(workspaceSettings, { workspaceInvitationsEnabled = true } = {}) {
|
|
17
|
-
const source = workspaceSettings && typeof workspaceSettings === "object" ? workspaceSettings : {};
|
|
18
|
-
const invitesAvailable = workspaceInvitationsEnabled === true;
|
|
19
|
-
const invitesEnabled = invitesAvailable && source.invitesEnabled !== false;
|
|
20
|
-
const themePalettes = resolveWorkspaceThemePalettes(source);
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
lightPrimaryColor: themePalettes.light.color,
|
|
24
|
-
lightSecondaryColor: themePalettes.light.secondaryColor,
|
|
25
|
-
lightSurfaceColor: themePalettes.light.surfaceColor,
|
|
26
|
-
lightSurfaceVariantColor: themePalettes.light.surfaceVariantColor,
|
|
27
|
-
darkPrimaryColor: themePalettes.dark.color,
|
|
28
|
-
darkSecondaryColor: themePalettes.dark.secondaryColor,
|
|
29
|
-
darkSurfaceColor: themePalettes.dark.surfaceColor,
|
|
30
|
-
darkSurfaceVariantColor: themePalettes.dark.surfaceVariantColor,
|
|
31
|
-
invitesEnabled,
|
|
32
|
-
invitesAvailable,
|
|
33
|
-
invitesEffective: invitesAvailable && invitesEnabled
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function mapMembershipSummary(membership, workspace) {
|
|
38
|
-
if (!membership) {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
workspaceId: normalizeRecordId(workspace?.id || membership.workspaceId, { fallback: "" }),
|
|
44
|
-
roleSid: normalizeLowerText(membership.roleSid || "member") || "member",
|
|
45
|
-
status: normalizeLowerText(membership.status || "active") || "active"
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export {
|
|
50
|
-
mapMembershipSummary,
|
|
51
|
-
mapWorkspaceSettingsPublic,
|
|
52
|
-
mapWorkspaceSummary
|
|
53
|
-
};
|