@cocreate/organizations 1.28.5 → 1.30.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,17 @@
1
+ # [1.30.0](https://github.com/CoCreate-app/CoCreate-organizations/compare/v1.29.0...v1.30.0) (2025-09-20)
2
+
3
+
4
+ ### Features
5
+
6
+ * add createEnvironment function and enhance createEnvironments handling ([d8e28f9](https://github.com/CoCreate-app/CoCreate-organizations/commit/d8e28f9ef032783f73e31a1a811643cb49a3c32e))
7
+
8
+ # [1.29.0](https://github.com/CoCreate-app/CoCreate-organizations/compare/v1.28.5...v1.29.0) (2025-09-07)
9
+
10
+
11
+ ### Features
12
+
13
+ * enhance generateDB to include file key and update createOrganization logic ([143e1b2](https://github.com/CoCreate-app/CoCreate-organizations/commit/143e1b2be97ad2d519041d6cc6fedb401bbb42ec))
14
+
1
15
  ## [1.28.5](https://github.com/CoCreate-app/CoCreate-organizations/compare/v1.28.4...v1.28.5) (2025-09-03)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/organizations",
3
- "version": "1.28.5",
3
+ "version": "1.30.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",
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");
234
-
235
- if (!organization || !organization.object) return;
236
- if (!user || !user.object) return;
236
+ let data = await Elements.getData(form);
237
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(
@@ -268,6 +285,35 @@ async function create(action) {
268
285
  );
269
286
  }
270
287
 
288
+ async function createEnvironment(action) {
289
+ let form = action.form;
290
+ if (!form) return;
291
+
292
+ let organization = form.querySelector("#organization");
293
+ if (organization) {
294
+ organization = organization.value;
295
+ }
296
+
297
+ let hostname = form.querySelector("#hostname");
298
+ if (hostname) {
299
+ hostname = hostname.value;
300
+ hostname = ["dev." + hostname, "test." + hostname];
301
+ }
302
+
303
+ let response = await Crud.socket.send({
304
+ method: "createEnvironments",
305
+ organization,
306
+ hostname,
307
+ broadcastBrowser: false
308
+ });
309
+
310
+ action.element.dispatchEvent(
311
+ new CustomEvent("createdEnvironments", {
312
+ detail: response
313
+ })
314
+ );
315
+ }
316
+
271
317
  Action.init({
272
318
  name: "createOrganization",
273
319
  endEvent: "createdOrganization",
@@ -275,5 +321,12 @@ Action.init({
275
321
  create(action);
276
322
  }
277
323
  });
324
+ Action.init({
325
+ name: "createEnvironments",
326
+ endEvent: "createdEnvironments",
327
+ callback: (action) => {
328
+ createEnvironment(action);
329
+ }
330
+ });
278
331
 
279
332
  export default { generateDB, create, get };
package/src/server.js CHANGED
@@ -15,6 +15,9 @@ class CoCreateOrganization {
15
15
  this.wsManager.on("createOrganization", (data) =>
16
16
  this.createOrganization(data)
17
17
  );
18
+ this.wsManager.on("createEnvironments", (data) =>
19
+ this.createEnvironments(data)
20
+ );
18
21
  }
19
22
  }
20
23
 
@@ -42,10 +45,10 @@ class CoCreateOrganization {
42
45
  );
43
46
  }
44
47
 
45
- if (!key || !Array.isArray(key) || key.length !== 3) {
48
+ if (!key || !Array.isArray(key) || key.length < 4) {
46
49
  this.errorHandler(
47
50
  data,
48
- "invalid_key: An array of 3 keys is required with type key, user and role."
51
+ "invalid_key: An array of 4 keys is required with type key, user and role."
49
52
  );
50
53
  }
51
54
 
@@ -55,12 +58,13 @@ class CoCreateOrganization {
55
58
  }
56
59
 
57
60
  const Data = {};
58
- Data.method = "object.create";
61
+ Data.method = "object.update";
59
62
  Data.host = organization.host[0].name;
60
- Data.database = organization._id;
63
+ Data.database = [organization._id];
61
64
  Data.organization_id = organization._id;
62
-
65
+ Data.upsert = true;
63
66
  if (organization) {
67
+ organization.organization_id = organization._id;
64
68
  const response = await this.crud.send({
65
69
  ...Data,
66
70
  array: "organizations",
@@ -71,6 +75,7 @@ class CoCreateOrganization {
71
75
  }
72
76
  }
73
77
  if (user) {
78
+ user.organization_id = organization._id;
74
79
  const response = await this.crud.send({
75
80
  ...Data,
76
81
  array: "users",
@@ -82,6 +87,9 @@ class CoCreateOrganization {
82
87
  }
83
88
 
84
89
  if (key) {
90
+ key.forEach(k => {
91
+ k.organization_id = organization._id;
92
+ });
85
93
  const response = await this.crud.send({
86
94
  ...Data,
87
95
  array: "keys",
@@ -105,6 +113,91 @@ class CoCreateOrganization {
105
113
  }
106
114
  }
107
115
 
116
+ async createEnvironments(data) {
117
+ try {
118
+ let { organization, hostname } = data;
119
+
120
+ if (!organization) {
121
+ this.errorHandler(
122
+ data,
123
+ "Missing required field: 'organization'. Please provide the organization object to create an organization."
124
+ );
125
+ }
126
+ if (!hostname) {
127
+ this.errorHandler(
128
+ data,
129
+ "Missing required field: 'hostname'. Please provide the hostname to create an organization."
130
+ );
131
+ }
132
+
133
+ // If there are validation errors, include them in the response and send immediately
134
+ if (data.success === false) {
135
+ return this.wsManager.send(data);
136
+ }
137
+
138
+ const Data = {};
139
+ Data.method = "object.read";
140
+ Data.host = hostname;
141
+ Data.organization_id = organization;
142
+ Data.$filter = { limit: 0 };
143
+
144
+ let organizations = await this.crud.send({
145
+ ...Data,
146
+ array: "organizations",
147
+ object: []
148
+ });
149
+
150
+ if (organizations.error) {
151
+ this.errorHandler(data, organizations.error);
152
+ }
153
+
154
+ let users = await this.crud.send({
155
+ ...Data,
156
+ array: "users",
157
+ object: []
158
+ });
159
+
160
+ if (users.error) {
161
+ this.errorHandler(data, users.error);
162
+ }
163
+
164
+ let keys = await this.crud.send({
165
+ ...Data,
166
+ array: "keys",
167
+ object: []
168
+ });
169
+
170
+ if (keys.error) {
171
+ this.errorHandler(data, keys.error);
172
+ }
173
+
174
+ for (let host of hostname) {
175
+ organizations.method = "object.create";
176
+ organizations.host = host;
177
+ organizations = await this.crud.send(organizations);
178
+
179
+ users.method = "object.create";
180
+ users.host = host;
181
+ users = await this.crud.send(users);
182
+
183
+ keys.method = "object.create";
184
+ keys.host = host;
185
+ keys = await this.crud.send(keys);
186
+ }
187
+
188
+ if (data.success !== false) {
189
+ data.success = true;
190
+ }
191
+
192
+ this.wsManager.send(data);
193
+ } catch (error) {
194
+ if (data.socket) {
195
+ this.errorHandler(data, error);
196
+ this.wsManager.send(data);
197
+ }
198
+ }
199
+ }
200
+
108
201
  errorHandler(data, error) {
109
202
  data.success = false;
110
203
  this.crud.errorHandler(data, error);