@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 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.28.4",
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.method = "object.create";
20
- organization.storage = "indexeddb";
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.method = "object.create";
30
- user.storage = "indexeddb";
31
- user.database = organization_id;
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 key = {
41
- method: "object.create",
42
- storage: "indexeddb",
43
- database: organization_id,
44
- array: "keys",
45
- object: {
46
- _id: Crud.ObjectId().toString(),
47
- type: "key",
48
- key: apikey,
49
- actions: {
50
- signIn: true,
51
- signUp: true
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
- default: true
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
- organization_id
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
- method: "object.create",
63
- storage: "indexeddb",
64
- database: organization_id,
65
- array: "keys",
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
- method: "object.create",
79
- storage: "indexeddb",
80
- database: organization_id,
81
- array: "keys",
82
- object: {
83
- _id: Crud.ObjectId().toString(),
84
- type: "user",
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: organization.object,
97
- apikey,
98
- user: user.object,
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, apikey, user } = await generateDB(org);
206
- if (organization && apikey && user) {
207
- Crud.socket.apikey = 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", 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 organization = Elements.getData(form, "organizations");
233
- let user = Elements.getData(form, "users");
236
+ let data = await Elements.getData(form);
234
237
 
235
- if (!organization || !organization.object) return;
236
- if (!user || !user.object) return;
237
-
238
- if (!organization.object._id && !user.object._id) {
239
- let objects = await generateDB(organization, user);
240
- if (!objects) return;
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
- Elements.setTypeValue(form, organization);
244
- Elements.setTypeValue(form, user);
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
- organization = organization.object[0];
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
- organization,
259
- user,
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
- 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
- }
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
- init() {
14
- if (this.wsManager) {
15
- this.wsManager.on('createOrganization', (data) =>
16
- this.createOrganization(data)
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
- async createOrganization(data) {
22
- try {
23
- if (!data.organization || !data.organization._id) return
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
- const organization = {
27
- _id: data.organization._id,
28
- name: data.organization.name || 'untitled',
29
- host: data.organization.host || [],
30
- owner: data.user._id,
31
- balance: 10, // TODO: set balance to 0 and create a transcation with type credit to add the $10
32
- dataTransfered: 0
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
- // TODO: check if user exist and confirm credentials
36
- const user = {
37
- _id: data.user._id,
38
- firstname: data.user.firtname || 'Admin',
39
- lastname: data.user.lastname || ''
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
- const userKey = {
43
- type: "user",
44
- key: user._id,
45
- roles: ['user'],
46
- email: user.object.email,
47
- password: user.object.password || btoa('0000'),
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
- const Data = {}
54
- Data.method = 'object.create'
55
- Data.host = data.host
56
- Data.database = process.env.organization_id
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
- if (organization) {
60
- const response = await this.crud.send({ ...Data, array: 'organizations', object: organization })
61
- this.wsManager.send(this.platformSocket, response);
62
- }
63
- if (user) {
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
- if (userKey) {
69
- const response = await this.crud.send({ ...Data, array: 'keys', object: userKey })
70
- this.wsManager.send(this.platformSocket, response);
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
- this.wsManager.send(data);
74
- } catch (error) {
75
- console.log('createObject error', error);
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;