@stndrds/schema 1.0.0-alpha.76 → 1.0.0-alpha.78
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/dist/{chunk-JZO52C3F.js → chunk-7WT53FJ4.js} +14 -9
- package/dist/{chunk-6P3NPTYV.mjs → chunk-AGBBH7PL.mjs} +15 -10
- package/dist/{chunk-JEOP4TFZ.mjs → chunk-JYXUFVUD.mjs} +155 -41
- package/dist/{chunk-27O7E2WM.js → chunk-KGEV5PIT.js} +329 -215
- package/dist/default-roles-5K3GHJTS.js +23 -0
- package/dist/{default-roles-OAMHLOCS.mjs → default-roles-6D3HQ3DQ.mjs} +3 -3
- package/dist/index.d.mts +10 -8
- package/dist/index.d.ts +10 -8
- package/dist/index.js +23 -7
- package/dist/index.mjs +21 -5
- package/dist/{runtime-VuCTBbS6.d.ts → runtime-Df0uvz45.d.ts} +58 -24
- package/dist/{runtime-Cv41_Suf.d.mts → runtime-ntcKC7g8.d.mts} +58 -24
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +2 -3
- package/dist/runtime.mjs +1 -2
- package/package.json +2 -2
- package/dist/default-roles-76HUWY6T.js +0 -23
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
var SYSTEM_RESOURCES = {
|
|
3
3
|
/** User profiles, invitations, roles and permissions management */
|
|
4
4
|
PEOPLE: "people",
|
|
5
|
-
/**
|
|
6
|
-
WORKSPACE: "workspace"
|
|
5
|
+
/** Tenant settings, audit logs, workflow execution, document generation */
|
|
6
|
+
WORKSPACE: "workspace",
|
|
7
|
+
/** Object definitions, attributes, views, workflow definitions */
|
|
8
|
+
ARCHITECT: "architect"
|
|
7
9
|
};
|
|
8
10
|
var ALL_SYSTEM_RESOURCES = [
|
|
9
11
|
SYSTEM_RESOURCES.PEOPLE,
|
|
10
|
-
SYSTEM_RESOURCES.WORKSPACE
|
|
12
|
+
SYSTEM_RESOURCES.WORKSPACE,
|
|
13
|
+
SYSTEM_RESOURCES.ARCHITECT
|
|
11
14
|
];
|
|
12
15
|
var SYSTEM_RESOURCE_LABELS = {
|
|
13
16
|
people: "People",
|
|
14
|
-
workspace: "Workspace"
|
|
17
|
+
workspace: "Workspace",
|
|
18
|
+
architect: "Architect"
|
|
15
19
|
};
|
|
16
20
|
var DEFAULT_ROLES = {
|
|
17
21
|
/** Full platform access - can manage everything */
|
|
@@ -34,16 +38,17 @@ var DEFAULT_ROLE_PERMISSIONS = {
|
|
|
34
38
|
object: [{ target: "*", actions: ALL_ACTIONS }]
|
|
35
39
|
},
|
|
36
40
|
member: {
|
|
37
|
-
system: [
|
|
41
|
+
system: [
|
|
42
|
+
{ target: "people", actions: ["read"] },
|
|
43
|
+
{ target: "workspace", actions: ["read"] }
|
|
44
|
+
],
|
|
38
45
|
object: [{ target: "*", actions: ALL_ACTIONS }]
|
|
39
46
|
}
|
|
40
47
|
};
|
|
48
|
+
var DEFAULT_ROLE_FOR_NEW_USERS = "member";
|
|
41
49
|
function isDefaultRole(roleName) {
|
|
42
50
|
return Object.values(DEFAULT_ROLES).includes(roleName);
|
|
43
51
|
}
|
|
44
|
-
function isAdminRole(roleName) {
|
|
45
|
-
return roleName === DEFAULT_ROLES.OWNER;
|
|
46
|
-
}
|
|
47
52
|
|
|
48
53
|
|
|
49
54
|
|
|
@@ -55,4 +60,4 @@ function isAdminRole(roleName) {
|
|
|
55
60
|
|
|
56
61
|
|
|
57
62
|
|
|
58
|
-
exports.SYSTEM_RESOURCES = SYSTEM_RESOURCES; exports.ALL_SYSTEM_RESOURCES = ALL_SYSTEM_RESOURCES; exports.SYSTEM_RESOURCE_LABELS = SYSTEM_RESOURCE_LABELS; exports.DEFAULT_ROLES = DEFAULT_ROLES; exports.DEFAULT_ROLE_LABELS = DEFAULT_ROLE_LABELS; exports.DEFAULT_ROLE_DESCRIPTIONS = DEFAULT_ROLE_DESCRIPTIONS; exports.DEFAULT_ROLE_PERMISSIONS = DEFAULT_ROLE_PERMISSIONS; exports.
|
|
63
|
+
exports.SYSTEM_RESOURCES = SYSTEM_RESOURCES; exports.ALL_SYSTEM_RESOURCES = ALL_SYSTEM_RESOURCES; exports.SYSTEM_RESOURCE_LABELS = SYSTEM_RESOURCE_LABELS; exports.DEFAULT_ROLES = DEFAULT_ROLES; exports.DEFAULT_ROLE_LABELS = DEFAULT_ROLE_LABELS; exports.DEFAULT_ROLE_DESCRIPTIONS = DEFAULT_ROLE_DESCRIPTIONS; exports.DEFAULT_ROLE_PERMISSIONS = DEFAULT_ROLE_PERMISSIONS; exports.DEFAULT_ROLE_FOR_NEW_USERS = DEFAULT_ROLE_FOR_NEW_USERS; exports.isDefaultRole = isDefaultRole;
|
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
var SYSTEM_RESOURCES = {
|
|
3
3
|
/** User profiles, invitations, roles and permissions management */
|
|
4
4
|
PEOPLE: "people",
|
|
5
|
-
/**
|
|
6
|
-
WORKSPACE: "workspace"
|
|
5
|
+
/** Tenant settings, audit logs, workflow execution, document generation */
|
|
6
|
+
WORKSPACE: "workspace",
|
|
7
|
+
/** Object definitions, attributes, views, workflow definitions */
|
|
8
|
+
ARCHITECT: "architect"
|
|
7
9
|
};
|
|
8
10
|
var ALL_SYSTEM_RESOURCES = [
|
|
9
11
|
SYSTEM_RESOURCES.PEOPLE,
|
|
10
|
-
SYSTEM_RESOURCES.WORKSPACE
|
|
12
|
+
SYSTEM_RESOURCES.WORKSPACE,
|
|
13
|
+
SYSTEM_RESOURCES.ARCHITECT
|
|
11
14
|
];
|
|
12
15
|
var SYSTEM_RESOURCE_LABELS = {
|
|
13
16
|
people: "People",
|
|
14
|
-
workspace: "Workspace"
|
|
17
|
+
workspace: "Workspace",
|
|
18
|
+
architect: "Architect"
|
|
15
19
|
};
|
|
16
20
|
var DEFAULT_ROLES = {
|
|
17
21
|
/** Full platform access - can manage everything */
|
|
@@ -34,16 +38,17 @@ var DEFAULT_ROLE_PERMISSIONS = {
|
|
|
34
38
|
object: [{ target: "*", actions: ALL_ACTIONS }]
|
|
35
39
|
},
|
|
36
40
|
member: {
|
|
37
|
-
system: [
|
|
41
|
+
system: [
|
|
42
|
+
{ target: "people", actions: ["read"] },
|
|
43
|
+
{ target: "workspace", actions: ["read"] }
|
|
44
|
+
],
|
|
38
45
|
object: [{ target: "*", actions: ALL_ACTIONS }]
|
|
39
46
|
}
|
|
40
47
|
};
|
|
48
|
+
var DEFAULT_ROLE_FOR_NEW_USERS = "member";
|
|
41
49
|
function isDefaultRole(roleName) {
|
|
42
50
|
return Object.values(DEFAULT_ROLES).includes(roleName);
|
|
43
51
|
}
|
|
44
|
-
function isAdminRole(roleName) {
|
|
45
|
-
return roleName === DEFAULT_ROLES.OWNER;
|
|
46
|
-
}
|
|
47
52
|
|
|
48
53
|
export {
|
|
49
54
|
SYSTEM_RESOURCES,
|
|
@@ -53,6 +58,6 @@ export {
|
|
|
53
58
|
DEFAULT_ROLE_LABELS,
|
|
54
59
|
DEFAULT_ROLE_DESCRIPTIONS,
|
|
55
60
|
DEFAULT_ROLE_PERMISSIONS,
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
DEFAULT_ROLE_FOR_NEW_USERS,
|
|
62
|
+
isDefaultRole
|
|
58
63
|
};
|
|
@@ -13,9 +13,6 @@ import {
|
|
|
13
13
|
validateObject,
|
|
14
14
|
validateObjectOrThrow
|
|
15
15
|
} from "./chunk-5SZ5OISG.mjs";
|
|
16
|
-
import {
|
|
17
|
-
isAdminRole
|
|
18
|
-
} from "./chunk-6P3NPTYV.mjs";
|
|
19
16
|
import {
|
|
20
17
|
__require
|
|
21
18
|
} from "./chunk-Y6FXYEAI.mjs";
|
|
@@ -3210,6 +3207,17 @@ function createMockObjectsRepository(stores) {
|
|
|
3210
3207
|
);
|
|
3211
3208
|
return Promise.resolve(results);
|
|
3212
3209
|
},
|
|
3210
|
+
deleteSystemNotInNames(excludeNames) {
|
|
3211
|
+
const tenantId = getTenantId();
|
|
3212
|
+
let count = 0;
|
|
3213
|
+
for (const [id, obj] of stores.objects.entries()) {
|
|
3214
|
+
if (obj.tenantId === tenantId && obj.system && !excludeNames.includes(obj.name)) {
|
|
3215
|
+
stores.objects.delete(id);
|
|
3216
|
+
count++;
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
return Promise.resolve(count);
|
|
3220
|
+
},
|
|
3213
3221
|
upsert(data) {
|
|
3214
3222
|
const tenantId = getTenantId();
|
|
3215
3223
|
for (const obj of stores.objects.values()) {
|
|
@@ -4579,8 +4587,6 @@ function createMockPermissionsRepository(stores) {
|
|
|
4579
4587
|
getEffectivePermissions(userProfileId) {
|
|
4580
4588
|
const tenantId = getTenantId();
|
|
4581
4589
|
const userRoleIds = Array.from(stores.userRoles.values()).filter((ur) => ur.userProfileId === userProfileId && ur.tenantId === tenantId).map((ur) => ur.roleId);
|
|
4582
|
-
const userRoles = Array.from(stores.roles.values()).filter((r) => userRoleIds.includes(r.id));
|
|
4583
|
-
const hasAdmin = userRoles.some((r) => isAdminRole(r.name));
|
|
4584
4590
|
const userPermissions = Array.from(stores.permissions.values()).filter(
|
|
4585
4591
|
(p) => userRoleIds.includes(p.roleId)
|
|
4586
4592
|
);
|
|
@@ -4607,7 +4613,7 @@ function createMockPermissionsRepository(stores) {
|
|
|
4607
4613
|
}
|
|
4608
4614
|
}
|
|
4609
4615
|
}
|
|
4610
|
-
return Promise.resolve({
|
|
4616
|
+
return Promise.resolve({ objectPermissions, systemPermissions });
|
|
4611
4617
|
},
|
|
4612
4618
|
countUsersWithRole(roleName) {
|
|
4613
4619
|
const tenantId = getTenantId();
|
|
@@ -9856,15 +9862,31 @@ var AuditService = class extends BaseService {
|
|
|
9856
9862
|
if (!this.adapter.audit) {
|
|
9857
9863
|
return;
|
|
9858
9864
|
}
|
|
9865
|
+
const resolved = await this.resolveActorEmail(entry);
|
|
9859
9866
|
if (this.options?.async) {
|
|
9860
|
-
this.buffer.push(
|
|
9867
|
+
this.buffer.push(resolved);
|
|
9861
9868
|
const batchSize = this.options.batchSize ?? 10;
|
|
9862
9869
|
if (this.buffer.length >= batchSize) {
|
|
9863
9870
|
await this.flush();
|
|
9864
9871
|
}
|
|
9865
9872
|
} else {
|
|
9866
|
-
await this.adapter.audit.create(
|
|
9873
|
+
await this.adapter.audit.create(resolved);
|
|
9874
|
+
}
|
|
9875
|
+
}
|
|
9876
|
+
/**
|
|
9877
|
+
* Resolve actorEmail from user profiles if not already set
|
|
9878
|
+
*/
|
|
9879
|
+
async resolveActorEmail(entry) {
|
|
9880
|
+
if (!entry.actorEmail && entry.actorId) {
|
|
9881
|
+
try {
|
|
9882
|
+
const profile = await this.adapter.userProfiles.findById(entry.actorId);
|
|
9883
|
+
if (profile?.email) {
|
|
9884
|
+
return { ...entry, actorEmail: profile.email };
|
|
9885
|
+
}
|
|
9886
|
+
} catch {
|
|
9887
|
+
}
|
|
9867
9888
|
}
|
|
9889
|
+
return entry;
|
|
9868
9890
|
}
|
|
9869
9891
|
/**
|
|
9870
9892
|
* Start the flush timer for async mode
|
|
@@ -15112,6 +15134,74 @@ var UserProfileService = class extends BaseService {
|
|
|
15112
15134
|
await this.invalidateCache(cacheKeys.userProfileByEmail(this.tenantId, email));
|
|
15113
15135
|
}
|
|
15114
15136
|
}
|
|
15137
|
+
// ============================================================================
|
|
15138
|
+
// AVATAR URL RESOLUTION
|
|
15139
|
+
// ============================================================================
|
|
15140
|
+
/**
|
|
15141
|
+
* Resolve avatar storage path to a signed URL.
|
|
15142
|
+
* External URLs (https://) pass through unchanged.
|
|
15143
|
+
* Storage paths are resolved to fresh signed URLs (1h expiry).
|
|
15144
|
+
*/
|
|
15145
|
+
async resolveAvatarUrl(profile) {
|
|
15146
|
+
if (!profile.avatarUrl || profile.avatarUrl.startsWith("https://")) {
|
|
15147
|
+
return profile;
|
|
15148
|
+
}
|
|
15149
|
+
if (!this.adapter.storage) return profile;
|
|
15150
|
+
try {
|
|
15151
|
+
const signedUrl = await this.adapter.storage.getSignedUrl(profile.avatarUrl, {
|
|
15152
|
+
expiresIn: 3600
|
|
15153
|
+
});
|
|
15154
|
+
return { ...profile, avatarUrl: signedUrl };
|
|
15155
|
+
} catch {
|
|
15156
|
+
return profile;
|
|
15157
|
+
}
|
|
15158
|
+
}
|
|
15159
|
+
async resolveAvatarUrls(profiles) {
|
|
15160
|
+
return Promise.all(profiles.map((p) => this.resolveAvatarUrl(p)));
|
|
15161
|
+
}
|
|
15162
|
+
// ============================================================================
|
|
15163
|
+
// AVATAR MANAGEMENT
|
|
15164
|
+
// ============================================================================
|
|
15165
|
+
/**
|
|
15166
|
+
* Upload a new avatar for the user.
|
|
15167
|
+
* Deletes previous avatar from storage if it was an internal upload.
|
|
15168
|
+
* Stores the storagePath — resolved to signed URL at read time.
|
|
15169
|
+
*/
|
|
15170
|
+
async uploadAvatar(profileId, input) {
|
|
15171
|
+
if (!this.adapter.storage) {
|
|
15172
|
+
throw new Error("StorageAdapter is not configured.");
|
|
15173
|
+
}
|
|
15174
|
+
if (!input.mimeType.startsWith("image/")) {
|
|
15175
|
+
throw new Error("Only image files are allowed for avatars.");
|
|
15176
|
+
}
|
|
15177
|
+
const profile = await this.getProfileOrThrow(profileId);
|
|
15178
|
+
if (profile.avatarUrl && !profile.avatarUrl.startsWith("https://")) {
|
|
15179
|
+
await this.adapter.storage.delete(profile.avatarUrl).catch(() => void 0);
|
|
15180
|
+
}
|
|
15181
|
+
const result = await this.adapter.storage.upload({
|
|
15182
|
+
content: input.content,
|
|
15183
|
+
fileName: input.fileName,
|
|
15184
|
+
mimeType: input.mimeType,
|
|
15185
|
+
size: input.size,
|
|
15186
|
+
tenantId: this.tenantId,
|
|
15187
|
+
folderPath: "avatars"
|
|
15188
|
+
});
|
|
15189
|
+
return await this.updateProfile(profileId, { avatarUrl: result.storagePath });
|
|
15190
|
+
}
|
|
15191
|
+
/**
|
|
15192
|
+
* Delete the user's avatar.
|
|
15193
|
+
* Removes file from storage if it was an internal upload, then clears avatarUrl.
|
|
15194
|
+
*/
|
|
15195
|
+
async deleteAvatar(profileId) {
|
|
15196
|
+
const profile = await this.getProfileOrThrow(profileId);
|
|
15197
|
+
if (profile.avatarUrl && !profile.avatarUrl.startsWith("https://")) {
|
|
15198
|
+
await this.adapter.storage?.delete(profile.avatarUrl).catch(() => void 0);
|
|
15199
|
+
}
|
|
15200
|
+
return await this.updateProfile(profileId, { avatarUrl: null });
|
|
15201
|
+
}
|
|
15202
|
+
// ============================================================================
|
|
15203
|
+
// CREATE
|
|
15204
|
+
// ============================================================================
|
|
15115
15205
|
/**
|
|
15116
15206
|
* Create a new user profile (typically after first auth).
|
|
15117
15207
|
* Automatically uses tenant context from AsyncLocalStorage.
|
|
@@ -15152,18 +15242,19 @@ var UserProfileService = class extends BaseService {
|
|
|
15152
15242
|
targetUserEmail: profile.email
|
|
15153
15243
|
});
|
|
15154
15244
|
}
|
|
15155
|
-
return profile;
|
|
15245
|
+
return this.resolveAvatarUrl(profile);
|
|
15156
15246
|
}
|
|
15157
15247
|
/**
|
|
15158
15248
|
* Get user profile by ID.
|
|
15159
15249
|
* Results are cached if a CacheAdapter is configured.
|
|
15160
15250
|
*/
|
|
15161
15251
|
async getProfile(profileId) {
|
|
15162
|
-
|
|
15252
|
+
const profile = await this.cachedBy(
|
|
15163
15253
|
"userProfileById",
|
|
15164
15254
|
profileId,
|
|
15165
15255
|
() => this.adapter.userProfiles.findById(profileId)
|
|
15166
15256
|
);
|
|
15257
|
+
return profile ? this.resolveAvatarUrl(profile) : null;
|
|
15167
15258
|
}
|
|
15168
15259
|
/**
|
|
15169
15260
|
* Get user profile by ID or throw
|
|
@@ -15185,11 +15276,12 @@ var UserProfileService = class extends BaseService {
|
|
|
15185
15276
|
* @returns User profile or null
|
|
15186
15277
|
*/
|
|
15187
15278
|
async getProfileByAuthId(authId) {
|
|
15188
|
-
|
|
15279
|
+
const profile = await this.cachedBy(
|
|
15189
15280
|
"userProfileByAuthId",
|
|
15190
15281
|
authId,
|
|
15191
15282
|
() => this.adapter.userProfiles.findByAuthId(authId)
|
|
15192
15283
|
);
|
|
15284
|
+
return profile ? this.resolveAvatarUrl(profile) : null;
|
|
15193
15285
|
}
|
|
15194
15286
|
/**
|
|
15195
15287
|
* Get or create user profile (idempotent operation)
|
|
@@ -15228,11 +15320,11 @@ var UserProfileService = class extends BaseService {
|
|
|
15228
15320
|
const updated = await this.adapter.userProfiles.update(profileId, data);
|
|
15229
15321
|
await this.invalidateProfileCache(updated.id, updated.authId, updated.email);
|
|
15230
15322
|
if (this.auditService && this.userId) {
|
|
15231
|
-
const changes = buildAuditChanges(
|
|
15232
|
-
|
|
15233
|
-
|
|
15234
|
-
"status"
|
|
15235
|
-
|
|
15323
|
+
const changes = buildAuditChanges(
|
|
15324
|
+
existing,
|
|
15325
|
+
data,
|
|
15326
|
+
["firstName", "lastName", "status"]
|
|
15327
|
+
);
|
|
15236
15328
|
if (changes.length > 0) {
|
|
15237
15329
|
await this.auditService.logUserAction({
|
|
15238
15330
|
action: "user.updated",
|
|
@@ -15243,7 +15335,7 @@ var UserProfileService = class extends BaseService {
|
|
|
15243
15335
|
});
|
|
15244
15336
|
}
|
|
15245
15337
|
}
|
|
15246
|
-
return updated;
|
|
15338
|
+
return this.resolveAvatarUrl(updated);
|
|
15247
15339
|
}
|
|
15248
15340
|
/**
|
|
15249
15341
|
* Delete user profile.
|
|
@@ -15280,7 +15372,8 @@ var UserProfileService = class extends BaseService {
|
|
|
15280
15372
|
* Automatically uses tenant context from AsyncLocalStorage.
|
|
15281
15373
|
*/
|
|
15282
15374
|
async listProfiles(options) {
|
|
15283
|
-
|
|
15375
|
+
const profiles = await this.adapter.userProfiles.list(options);
|
|
15376
|
+
return this.resolveAvatarUrls(profiles);
|
|
15284
15377
|
}
|
|
15285
15378
|
/**
|
|
15286
15379
|
* Update last login timestamp
|
|
@@ -15311,11 +15404,12 @@ var UserProfileService = class extends BaseService {
|
|
|
15311
15404
|
* Automatically uses tenant context from AsyncLocalStorage.
|
|
15312
15405
|
*/
|
|
15313
15406
|
async getProfileByEmail(email) {
|
|
15314
|
-
|
|
15407
|
+
const profile = await this.cachedBy(
|
|
15315
15408
|
"userProfileByEmail",
|
|
15316
15409
|
email,
|
|
15317
15410
|
() => this.adapter.userProfiles.findByEmail(email)
|
|
15318
15411
|
);
|
|
15412
|
+
return profile ? this.resolveAvatarUrl(profile) : null;
|
|
15319
15413
|
}
|
|
15320
15414
|
/**
|
|
15321
15415
|
* Invite a new user by email.
|
|
@@ -15348,6 +15442,21 @@ var UserProfileService = class extends BaseService {
|
|
|
15348
15442
|
throw new Error(`User with email "${data.email}" already exists in this tenant`);
|
|
15349
15443
|
}
|
|
15350
15444
|
const profile = await this.adapter.userProfiles.invite(data);
|
|
15445
|
+
if (this.adapter.permissions) {
|
|
15446
|
+
try {
|
|
15447
|
+
const roles = await this.adapter.permissions.getRoles();
|
|
15448
|
+
const defaultRole = roles.find((r) => r.name === "member" && r.system);
|
|
15449
|
+
if (defaultRole) {
|
|
15450
|
+
await this.adapter.permissions.assignRole({
|
|
15451
|
+
userProfileId: profile.id,
|
|
15452
|
+
roleId: defaultRole.id,
|
|
15453
|
+
tenantId: this.tenantId,
|
|
15454
|
+
assignedBy: this.userId ?? void 0
|
|
15455
|
+
});
|
|
15456
|
+
}
|
|
15457
|
+
} catch {
|
|
15458
|
+
}
|
|
15459
|
+
}
|
|
15351
15460
|
await this.invalidateProfileCache(profile.id, profile.authId, profile.email);
|
|
15352
15461
|
if (this.auditService && this.userId) {
|
|
15353
15462
|
await this.auditService.logUserAction({
|
|
@@ -15357,7 +15466,7 @@ var UserProfileService = class extends BaseService {
|
|
|
15357
15466
|
targetUserEmail: profile.email
|
|
15358
15467
|
});
|
|
15359
15468
|
}
|
|
15360
|
-
return profile;
|
|
15469
|
+
return this.resolveAvatarUrl(profile);
|
|
15361
15470
|
}
|
|
15362
15471
|
};
|
|
15363
15472
|
|
|
@@ -17030,14 +17139,11 @@ var FileService = class extends BaseService {
|
|
|
17030
17139
|
* @param userId - User ID to check
|
|
17031
17140
|
* @returns true if user can access the file
|
|
17032
17141
|
*/
|
|
17033
|
-
async checkAccess(fileId, userId
|
|
17142
|
+
async checkAccess(fileId, userId) {
|
|
17034
17143
|
const file2 = await this.getFile(fileId);
|
|
17035
17144
|
if (!file2) {
|
|
17036
17145
|
return false;
|
|
17037
17146
|
}
|
|
17038
|
-
if (options?.isAdmin) {
|
|
17039
|
-
return true;
|
|
17040
|
-
}
|
|
17041
17147
|
if (file2.visibility === "public") {
|
|
17042
17148
|
return true;
|
|
17043
17149
|
}
|
|
@@ -17321,9 +17427,6 @@ var PermissionService = class extends BaseService {
|
|
|
17321
17427
|
*/
|
|
17322
17428
|
async canAccessObject(userProfileId, objectName, action) {
|
|
17323
17429
|
const permissions = await this.getEffectivePermissions(userProfileId);
|
|
17324
|
-
if (permissions.isAdmin) {
|
|
17325
|
-
return true;
|
|
17326
|
-
}
|
|
17327
17430
|
const wildcardPerms = permissions.objectPermissions["*"];
|
|
17328
17431
|
if (wildcardPerms?.includes(action)) {
|
|
17329
17432
|
return true;
|
|
@@ -17355,9 +17458,6 @@ var PermissionService = class extends BaseService {
|
|
|
17355
17458
|
*/
|
|
17356
17459
|
async getObjectPermissions(userProfileId, objectName) {
|
|
17357
17460
|
const permissions = await this.getEffectivePermissions(userProfileId);
|
|
17358
|
-
if (permissions.isAdmin) {
|
|
17359
|
-
return { canRead: true, canCreate: true, canUpdate: true, canDelete: true };
|
|
17360
|
-
}
|
|
17361
17461
|
const wildcardPerms = permissions.objectPermissions["*"] ?? [];
|
|
17362
17462
|
const objectPerms = permissions.objectPermissions[objectName] ?? [];
|
|
17363
17463
|
const allPerms = /* @__PURE__ */ new Set([...wildcardPerms, ...objectPerms]);
|
|
@@ -17381,9 +17481,6 @@ var PermissionService = class extends BaseService {
|
|
|
17381
17481
|
*/
|
|
17382
17482
|
async canAccessSystem(userProfileId, resource, action) {
|
|
17383
17483
|
const permissions = await this.getEffectivePermissions(userProfileId);
|
|
17384
|
-
if (permissions.isAdmin) {
|
|
17385
|
-
return true;
|
|
17386
|
-
}
|
|
17387
17484
|
const wildcardPerms = permissions.systemPermissions?.["*"];
|
|
17388
17485
|
if (wildcardPerms?.includes(action)) {
|
|
17389
17486
|
return true;
|
|
@@ -17415,9 +17512,6 @@ var PermissionService = class extends BaseService {
|
|
|
17415
17512
|
*/
|
|
17416
17513
|
async getSystemPermissions(userProfileId, resource) {
|
|
17417
17514
|
const permissions = await this.getEffectivePermissions(userProfileId);
|
|
17418
|
-
if (permissions.isAdmin) {
|
|
17419
|
-
return { canRead: true, canCreate: true, canUpdate: true, canDelete: true };
|
|
17420
|
-
}
|
|
17421
17515
|
const wildcardPerms = permissions.systemPermissions?.["*"] ?? [];
|
|
17422
17516
|
const resourcePerms = permissions.systemPermissions?.[resource] ?? [];
|
|
17423
17517
|
const allPerms = /* @__PURE__ */ new Set([...wildcardPerms, ...resourcePerms]);
|
|
@@ -17622,9 +17716,8 @@ var PermissionService = class extends BaseService {
|
|
|
17622
17716
|
* Initialize default roles for the tenant if they don't exist.
|
|
17623
17717
|
*
|
|
17624
17718
|
* Creates the following roles with their default permissions:
|
|
17625
|
-
* - **
|
|
17626
|
-
* - **member**:
|
|
17627
|
-
* - **guest**: No system access, read-only access to objects
|
|
17719
|
+
* - **owner**: Full access to all system resources and objects
|
|
17720
|
+
* - **member**: Full CRUD on business data, read-only on system resources (people, workspace)
|
|
17628
17721
|
*
|
|
17629
17722
|
* This method is idempotent - it only creates roles that don't already exist.
|
|
17630
17723
|
* Should be called during tenant bootstrap or on first admin login.
|
|
@@ -17641,7 +17734,7 @@ var PermissionService = class extends BaseService {
|
|
|
17641
17734
|
DEFAULT_ROLE_LABELS,
|
|
17642
17735
|
DEFAULT_ROLE_DESCRIPTIONS,
|
|
17643
17736
|
DEFAULT_ROLE_PERMISSIONS
|
|
17644
|
-
} = await import("./default-roles-
|
|
17737
|
+
} = await import("./default-roles-6D3HQ3DQ.mjs");
|
|
17645
17738
|
const existingRoles = await this.getRoles();
|
|
17646
17739
|
const existingRoleNames = existingRoles.reduce((set, r) => set.add(r.name), /* @__PURE__ */ new Set());
|
|
17647
17740
|
for (const roleName of Object.values(DEFAULT_ROLES)) {
|
|
@@ -18426,6 +18519,7 @@ async function syncNativeObjects(adapter, nativeRegistry, options = {}) {
|
|
|
18426
18519
|
const result = {
|
|
18427
18520
|
success: true,
|
|
18428
18521
|
objectsSynced: 0,
|
|
18522
|
+
objectsDeleted: 0,
|
|
18429
18523
|
attributesSynced: 0,
|
|
18430
18524
|
objectsCreated: 0,
|
|
18431
18525
|
objectsUpdated: 0,
|
|
@@ -18451,6 +18545,7 @@ async function syncNativeObjects(adapter, nativeRegistry, options = {}) {
|
|
|
18451
18545
|
});
|
|
18452
18546
|
}
|
|
18453
18547
|
}
|
|
18548
|
+
await cleanupOrphanObjects(tx, nativeObjects, result, options);
|
|
18454
18549
|
});
|
|
18455
18550
|
} catch (error2) {
|
|
18456
18551
|
result.success = false;
|
|
@@ -18462,7 +18557,7 @@ async function syncNativeObjects(adapter, nativeRegistry, options = {}) {
|
|
|
18462
18557
|
if (options.verbose) {
|
|
18463
18558
|
console.info(
|
|
18464
18559
|
`[SyncService] ${result.success ? "\u2713" : "\u2717"} Sync complete:
|
|
18465
|
-
Objects: ${result.objectsCreated} created, ${result.objectsUpdated} updated
|
|
18560
|
+
Objects: ${result.objectsCreated} created, ${result.objectsUpdated} updated, ${result.objectsDeleted} deleted
|
|
18466
18561
|
Attributes: ${result.attributesCreated} created, ${result.attributesUpdated} updated, ${result.attributesDeleted} deleted
|
|
18467
18562
|
Errors: ${result.errors.length}`
|
|
18468
18563
|
);
|
|
@@ -18574,6 +18669,25 @@ async function cleanupAttributes(adapter, objectId, nativeObject, result) {
|
|
|
18574
18669
|
const deletedCount = await adapter.attributes.deleteSystemByNames(objectId, attributeNames);
|
|
18575
18670
|
result.attributesDeleted += deletedCount;
|
|
18576
18671
|
}
|
|
18672
|
+
async function cleanupOrphanObjects(adapter, nativeObjects, result, options) {
|
|
18673
|
+
const registryNames = nativeObjects.map((obj) => obj.name);
|
|
18674
|
+
if (options.dryRun) {
|
|
18675
|
+
const allObjects = await adapter.objects.list();
|
|
18676
|
+
const orphans = allObjects.filter((obj) => obj.system && !registryNames.includes(obj.name));
|
|
18677
|
+
result.objectsDeleted += orphans.length;
|
|
18678
|
+
if (options.verbose && orphans.length > 0) {
|
|
18679
|
+
console.info(
|
|
18680
|
+
`[SyncService] Would delete ${orphans.length} orphan system object(s): ${orphans.map((o) => o.name).join(", ")}`
|
|
18681
|
+
);
|
|
18682
|
+
}
|
|
18683
|
+
return;
|
|
18684
|
+
}
|
|
18685
|
+
const deletedCount = await adapter.objects.deleteSystemNotInNames(registryNames);
|
|
18686
|
+
result.objectsDeleted += deletedCount;
|
|
18687
|
+
if (options.verbose && deletedCount > 0) {
|
|
18688
|
+
console.info(`[SyncService] Deleted ${deletedCount} orphan system object(s)`);
|
|
18689
|
+
}
|
|
18690
|
+
}
|
|
18577
18691
|
function logSyncSuccess(nativeObject, options) {
|
|
18578
18692
|
if (options.verbose) {
|
|
18579
18693
|
console.info(
|