@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 +14 -0
- package/package.json +1 -1
- package/src/client.js +147 -94
- package/src/server.js +98 -5
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
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");
|
|
234
|
-
|
|
235
|
-
if (!organization || !organization.object) return;
|
|
236
|
-
if (!user || !user.object) return;
|
|
236
|
+
let data = await Elements.getData(form);
|
|
237
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(
|
|
@@ -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
|
|
48
|
+
if (!key || !Array.isArray(key) || key.length < 4) {
|
|
46
49
|
this.errorHandler(
|
|
47
50
|
data,
|
|
48
|
-
"invalid_key: An array of
|
|
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.
|
|
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);
|