@cocreate/organizations 1.28.4 → 1.29.0
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 +15 -0
- package/package.json +1 -9
- package/src/client.js +111 -94
- package/src/server.js +102 -68
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
# [1.29.0](https://github.com/CoCreate-app/CoCreate-organizations/compare/v1.28.5...v1.29.0) (2025-09-07)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* enhance generateDB to include file key and update createOrganization logic ([143e1b2](https://github.com/CoCreate-app/CoCreate-organizations/commit/143e1b2be97ad2d519041d6cc6fedb401bbb42ec))
|
|
7
|
+
|
|
8
|
+
## [1.28.5](https://github.com/CoCreate-app/CoCreate-organizations/compare/v1.28.4...v1.28.5) (2025-09-03)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* improve organization creation logic and error handling ([bfed09d](https://github.com/CoCreate-app/CoCreate-organizations/commit/bfed09df186993dccef4164674ac430fe4aec17b))
|
|
14
|
+
* streamline organization creation validation and error handling ([4e94111](https://github.com/CoCreate-app/CoCreate-organizations/commit/4e94111529c50be01f96424e5428c14b0d0e4b36))
|
|
15
|
+
|
|
1
16
|
## [1.28.4](https://github.com/CoCreate-app/CoCreate-organizations/compare/v1.28.3...v1.28.4) (2025-05-01)
|
|
2
17
|
|
|
3
18
|
|
package/package.json
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/organizations",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.29.0",
|
|
4
4
|
"description": "A simple organizations component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"organizations",
|
|
7
|
-
"cocreate",
|
|
8
|
-
"low-code-framework",
|
|
9
|
-
"no-code-framework",
|
|
10
|
-
"cocreatejs",
|
|
11
|
-
"cocreatejs-component",
|
|
12
|
-
"cocreate-framework",
|
|
13
|
-
"no-code",
|
|
14
7
|
"low-code",
|
|
15
|
-
"collaborative-framework",
|
|
16
8
|
"realtime",
|
|
17
9
|
"realtime-framework",
|
|
18
10
|
"collaboration",
|
package/src/client.js
CHANGED
|
@@ -5,105 +5,107 @@ import Config from "@cocreate/config";
|
|
|
5
5
|
import Indexeddb from "@cocreate/indexeddb";
|
|
6
6
|
import uuid from "@cocreate/uuid";
|
|
7
7
|
|
|
8
|
-
async function generateDB(
|
|
9
|
-
organization = { object: {} },
|
|
10
|
-
user = { object: {} }
|
|
11
|
-
) {
|
|
12
|
-
const organization_id =
|
|
13
|
-
organization.object._id || Crud.ObjectId().toString();
|
|
14
|
-
const apikey = organization.object.key || uuid.generate();
|
|
15
|
-
const user_id = user.object._id || Crud.ObjectId().toString();
|
|
16
|
-
|
|
8
|
+
async function generateDB(organization = {}, user = {}, key = []) {
|
|
17
9
|
try {
|
|
18
10
|
// Create organization
|
|
19
|
-
organization.
|
|
20
|
-
organization.
|
|
21
|
-
organization.database = organization_id;
|
|
22
|
-
organization.array = "organizations";
|
|
23
|
-
organization.object._id = organization_id;
|
|
24
|
-
organization.object.name = organization.object.name || "untitiled";
|
|
25
|
-
organization.organization_id = organization_id;
|
|
26
|
-
Indexeddb.send(organization);
|
|
11
|
+
organization._id = organization._id || Crud.ObjectId().toString();
|
|
12
|
+
organization.name = organization.name || "untitiled";
|
|
27
13
|
|
|
28
14
|
// Create user
|
|
29
|
-
user.
|
|
30
|
-
user.
|
|
31
|
-
user.
|
|
32
|
-
user.array = "users";
|
|
33
|
-
user.object._id = user_id;
|
|
34
|
-
user.object.firstname = user.object.firstname || "untitiled";
|
|
35
|
-
user.object.lastname = user.object.lastname || "untitiled";
|
|
36
|
-
user.organization_id = organization_id;
|
|
37
|
-
Indexeddb.send(user);
|
|
15
|
+
user._id = user._id || Crud.ObjectId().toString();
|
|
16
|
+
user.firstname = user.firstname || "untitiled";
|
|
17
|
+
user.lastname = user.lastname || "untitiled";
|
|
38
18
|
|
|
39
19
|
// Create default key
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
20
|
+
let defaultKey = {
|
|
21
|
+
_id: Crud.ObjectId().toString(),
|
|
22
|
+
type: "key",
|
|
23
|
+
key: uuid.generate(),
|
|
24
|
+
actions: {
|
|
25
|
+
object: {
|
|
26
|
+
"*": {
|
|
27
|
+
users: {
|
|
28
|
+
"_id.$eq": "$user_id"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
read: {
|
|
32
|
+
$array: ["ai", "blog-posts"]
|
|
33
|
+
}
|
|
52
34
|
},
|
|
53
|
-
|
|
35
|
+
checkSession: "true",
|
|
36
|
+
signIn: "true",
|
|
37
|
+
signUp: "true",
|
|
38
|
+
acceptInvite: "true",
|
|
39
|
+
forgotPassword: "true",
|
|
40
|
+
resetPassword: "true",
|
|
41
|
+
updateUserStatus: "true",
|
|
42
|
+
isUnique: "true",
|
|
43
|
+
inviteUser: "true"
|
|
54
44
|
},
|
|
55
|
-
|
|
45
|
+
default: true
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Create File key
|
|
49
|
+
let fileKey = {
|
|
50
|
+
_id: Crud.ObjectId().toString(),
|
|
51
|
+
type: "key",
|
|
52
|
+
key: uuid.generate(),
|
|
53
|
+
actions: {
|
|
54
|
+
object: {
|
|
55
|
+
"*": {
|
|
56
|
+
$array: {
|
|
57
|
+
files: true
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
56
62
|
};
|
|
57
|
-
Indexeddb.send(key);
|
|
58
63
|
|
|
59
64
|
// Create role
|
|
60
65
|
let role_id = Crud.ObjectId().toString();
|
|
61
66
|
let role = {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
object: {
|
|
67
|
-
_id: role_id,
|
|
68
|
-
type: "role",
|
|
69
|
-
name: "admin",
|
|
70
|
-
admin: "true"
|
|
71
|
-
},
|
|
72
|
-
organization_id
|
|
67
|
+
_id: role_id,
|
|
68
|
+
type: "role",
|
|
69
|
+
name: "admin",
|
|
70
|
+
admin: "true"
|
|
73
71
|
};
|
|
74
|
-
Indexeddb.send(role);
|
|
75
72
|
|
|
76
73
|
// Create user key
|
|
77
74
|
let userKey = {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
array: "
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
key: user_id,
|
|
86
|
-
array: "users", // could be any array
|
|
87
|
-
roles: [role_id],
|
|
88
|
-
email: user.object.email,
|
|
89
|
-
password: user.object.password || btoa("0000")
|
|
90
|
-
},
|
|
91
|
-
organization_id
|
|
75
|
+
_id: Crud.ObjectId().toString(),
|
|
76
|
+
type: "user",
|
|
77
|
+
key: user._id,
|
|
78
|
+
array: "users", // could be any array
|
|
79
|
+
roles: [role_id],
|
|
80
|
+
email: user.email,
|
|
81
|
+
password: user.password || btoa("0000")
|
|
92
82
|
};
|
|
93
|
-
Indexeddb.send(userKey);
|
|
94
83
|
|
|
95
84
|
return {
|
|
96
|
-
organization
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
role: role.object,
|
|
100
|
-
userKey: userKey.object
|
|
85
|
+
organization,
|
|
86
|
+
user,
|
|
87
|
+
key: [defaultKey, fileKey, userKey, role]
|
|
101
88
|
};
|
|
102
89
|
} catch (error) {
|
|
103
90
|
return false;
|
|
104
91
|
}
|
|
105
92
|
}
|
|
106
93
|
|
|
94
|
+
function saveLocally(objects) {
|
|
95
|
+
const organization_id = objects.organization._id;
|
|
96
|
+
for (let key of Object.keys(objects)) {
|
|
97
|
+
let data = {
|
|
98
|
+
method: "object.create",
|
|
99
|
+
storage: "indexeddb",
|
|
100
|
+
database: organization_id,
|
|
101
|
+
array: key + "s",
|
|
102
|
+
object: objects[key],
|
|
103
|
+
organization_id
|
|
104
|
+
};
|
|
105
|
+
Indexeddb.send(data);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
107
109
|
async function get() {
|
|
108
110
|
let organization_id = await getOrganizationFromServiceWorker();
|
|
109
111
|
if (!organization_id) {
|
|
@@ -202,14 +204,16 @@ async function createOrganizationPromise() {
|
|
|
202
204
|
try {
|
|
203
205
|
let org = { object: {} };
|
|
204
206
|
if (organization_id) org.object._id = organization_id;
|
|
205
|
-
let { organization,
|
|
206
|
-
if (organization &&
|
|
207
|
-
Crud.socket.apikey =
|
|
207
|
+
let { organization, fileKey, user, key } = await generateDB(org);
|
|
208
|
+
if (organization && key && user) {
|
|
209
|
+
Crud.socket.apikey = key[0].key;
|
|
208
210
|
Crud.socket.user_id = user._id;
|
|
209
211
|
Config.set("organization_id", organization._id);
|
|
210
|
-
Config.set("apikey",
|
|
212
|
+
Config.set("apikey", key[0].key);
|
|
211
213
|
Config.set("user_id", user._id);
|
|
212
214
|
Crud.socket.organization = true;
|
|
215
|
+
saveLocally;
|
|
216
|
+
({ organization, user, key, fileKey });
|
|
213
217
|
return organization._id;
|
|
214
218
|
}
|
|
215
219
|
} catch (error) {
|
|
@@ -229,24 +233,39 @@ async function create(action) {
|
|
|
229
233
|
let form = action.form;
|
|
230
234
|
if (!form) return;
|
|
231
235
|
|
|
232
|
-
let
|
|
233
|
-
let user = Elements.getData(form, "users");
|
|
236
|
+
let data = await Elements.getData(form);
|
|
234
237
|
|
|
235
|
-
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
let organization, user;
|
|
239
|
+
if (Array.isArray(data)) {
|
|
240
|
+
for (const item of data) {
|
|
241
|
+
if (item.array === "organizations") {
|
|
242
|
+
organization = item;
|
|
243
|
+
}
|
|
244
|
+
if (item.array === "users") {
|
|
245
|
+
user = item;
|
|
246
|
+
}
|
|
247
|
+
if (organization && user) {
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
241
251
|
}
|
|
242
252
|
|
|
243
|
-
|
|
244
|
-
|
|
253
|
+
organization.method = "object.read";
|
|
254
|
+
organization = await Crud.send(organization);
|
|
255
|
+
|
|
256
|
+
user.method = "object.read";
|
|
257
|
+
user = await Crud.send(user);
|
|
258
|
+
|
|
259
|
+
if (organization && organization.object && organization.object[0]) {
|
|
260
|
+
organization = organization.object[0];
|
|
261
|
+
}
|
|
262
|
+
if (user && user.object && user.object[0]) {
|
|
263
|
+
user = user.object[0];
|
|
264
|
+
}
|
|
245
265
|
|
|
246
|
-
|
|
247
|
-
user = user.object[0];
|
|
266
|
+
let objects = await generateDB(organization, user);
|
|
248
267
|
|
|
249
|
-
let organization_id = organization._id;
|
|
268
|
+
let organization_id = organization._id || objects.organization._id;
|
|
250
269
|
|
|
251
270
|
if (Crud.socket.organization !== true) {
|
|
252
271
|
Crud.socket.organization = true;
|
|
@@ -255,10 +274,8 @@ async function create(action) {
|
|
|
255
274
|
|
|
256
275
|
let response = await Crud.socket.send({
|
|
257
276
|
method: "createOrganization",
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
broadcastBrowser: false,
|
|
261
|
-
organization_id
|
|
277
|
+
...objects,
|
|
278
|
+
broadcastBrowser: false
|
|
262
279
|
});
|
|
263
280
|
|
|
264
281
|
action.element.dispatchEvent(
|
package/src/server.js
CHANGED
|
@@ -1,80 +1,114 @@
|
|
|
1
1
|
class CoCreateOrganization {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
constructor(crud) {
|
|
3
|
+
this.wsManager = crud.wsManager;
|
|
4
|
+
this.crud = crud;
|
|
5
|
+
this.platformSocket = {
|
|
6
|
+
config: {
|
|
7
|
+
organization_id: process.env.organization_id
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
this.init();
|
|
11
|
+
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
init() {
|
|
14
|
+
if (this.wsManager) {
|
|
15
|
+
this.wsManager.on("createOrganization", (data) =>
|
|
16
|
+
this.createOrganization(data)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (!data.user || !data.user._id || !data.user.email || !data.user.password) return
|
|
21
|
+
async createOrganization(data) {
|
|
22
|
+
try {
|
|
23
|
+
const { organization, user, key } = data;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
if (
|
|
26
|
+
!organization ||
|
|
27
|
+
!organization._id ||
|
|
28
|
+
!organization.host ||
|
|
29
|
+
!organization.host[0] ||
|
|
30
|
+
!organization.host[0].name
|
|
31
|
+
) {
|
|
32
|
+
this.errorHandler(
|
|
33
|
+
data,
|
|
34
|
+
"invalid_organization: missing required organization fields"
|
|
35
|
+
);
|
|
36
|
+
}
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
if (!user || !user._id || !user.email || !user.password) {
|
|
39
|
+
this.errorHandler(
|
|
40
|
+
data,
|
|
41
|
+
"invalid_user: missing required user fields"
|
|
42
|
+
);
|
|
43
|
+
}
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
user: {
|
|
49
|
-
array: 'users'
|
|
50
|
-
}
|
|
51
|
-
}
|
|
45
|
+
if (!key || !Array.isArray(key) || key.length !== 3) {
|
|
46
|
+
this.errorHandler(
|
|
47
|
+
data,
|
|
48
|
+
"invalid_key: An array of 3 keys is required with type key, user and role."
|
|
49
|
+
);
|
|
50
|
+
}
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Data.organization_id = process.env.organization_id
|
|
52
|
+
// If there are validation errors, include them in the response and send immediately
|
|
53
|
+
if (data.success === false) {
|
|
54
|
+
return this.wsManager.send(data);
|
|
55
|
+
}
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const response = await this.crud.send({ ...Data, array: 'users', object: user })
|
|
65
|
-
this.wsManager.send(this.platformSocket, response);
|
|
66
|
-
}
|
|
57
|
+
const Data = {};
|
|
58
|
+
Data.method = "object.create";
|
|
59
|
+
Data.host = organization.host[0].name;
|
|
60
|
+
Data.database = [organization._id, "dev", "test"];
|
|
61
|
+
Data.organization_id = organization._id;
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
if (organization) {
|
|
64
|
+
const response = await this.crud.send({
|
|
65
|
+
...Data,
|
|
66
|
+
array: "organizations",
|
|
67
|
+
object: organization
|
|
68
|
+
});
|
|
69
|
+
if (response.error) {
|
|
70
|
+
this.errorHandler(data, response.error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (user) {
|
|
74
|
+
const response = await this.crud.send({
|
|
75
|
+
...Data,
|
|
76
|
+
array: "users",
|
|
77
|
+
object: user
|
|
78
|
+
});
|
|
79
|
+
if (response.error) {
|
|
80
|
+
this.errorHandler(data, response.error);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
72
83
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
84
|
+
if (key) {
|
|
85
|
+
const response = await this.crud.send({
|
|
86
|
+
...Data,
|
|
87
|
+
array: "keys",
|
|
88
|
+
object: key
|
|
89
|
+
});
|
|
90
|
+
if (response.error) {
|
|
91
|
+
this.errorHandler(data, response.error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (data.success !== false) {
|
|
96
|
+
data.success = true;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this.wsManager.send(data);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (data.socket) {
|
|
102
|
+
this.errorHandler(data, error);
|
|
103
|
+
this.wsManager.send(data);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
errorHandler(data, error) {
|
|
109
|
+
data.success = false;
|
|
110
|
+
this.crud.errorHandler(data, error);
|
|
111
|
+
}
|
|
78
112
|
}
|
|
79
113
|
|
|
80
|
-
module.exports = CoCreateOrganization;
|
|
114
|
+
module.exports = CoCreateOrganization;
|