@cocreate/users 1.34.2 → 1.35.1

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,20 @@
1
+ ## [1.35.1](https://github.com/CoCreate-app/CoCreate-users/compare/v1.35.0...v1.35.1) (2024-02-13)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * dispatch userInvite event if succesful ([17510a4](https://github.com/CoCreate-app/CoCreate-users/commit/17510a450d145b2f9f36ba7c418963aa58c47875))
7
+ * updating users ([5e25fcb](https://github.com/CoCreate-app/CoCreate-users/commit/5e25fcbab8992854758109c786730097b65251c5))
8
+
9
+ # [1.35.0](https://github.com/CoCreate-app/CoCreate-users/compare/v1.34.2...v1.35.0) (2024-02-13)
10
+
11
+
12
+ ### Features
13
+
14
+ * acceptInvite ([4b3db33](https://github.com/CoCreate-app/CoCreate-users/commit/4b3db33c2057968f8b37b9f618de7120a4b6f36d))
15
+ * acceptUser ([45c6869](https://github.com/CoCreate-app/CoCreate-users/commit/45c68699f5d978f02b6f9d550a04b853da2d64f5))
16
+ * inviteUser function ([593d9ad](https://github.com/CoCreate-app/CoCreate-users/commit/593d9add42568a0fa87060595daffdbee662212f))
17
+
1
18
  ## [1.34.2](https://github.com/CoCreate-app/CoCreate-users/compare/v1.34.1...v1.34.2) (2024-02-05)
2
19
 
3
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/users",
3
- "version": "1.34.2",
3
+ "version": "1.35.1",
4
4
  "description": "A simple users component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "users",
package/src/client.js CHANGED
@@ -168,8 +168,12 @@ const CoCreateUser = {
168
168
 
169
169
  updateUserStatus: function (data) {
170
170
  this.redirect(data)
171
+ let statusEls
171
172
  if (data.user_id) {
172
- let statusEls = document.querySelectorAll(`[user-status][object='${data['user_id']}']`);
173
+ if (data.user_id === Crud.socket.user_id)
174
+ statusEls = document.querySelectorAll(`[user-status][object='${data['user_id']}'], [user-status][object='$user_id']`);
175
+ else
176
+ statusEls = document.querySelectorAll(`[user-status][object='${data['user_id']}']`);
173
177
 
174
178
  statusEls.forEach((el) => {
175
179
  el.setAttribute('user-status', data['userStatus']);
@@ -226,7 +230,94 @@ const CoCreateUser = {
226
230
 
227
231
  },
228
232
 
229
- // TODO: updatePassword()
233
+ inviteUser: async function (action) {
234
+ let email = action.form.querySelector('input[key="email"]');
235
+ if (!email)
236
+ return
237
+ else
238
+ email = await email.getValue()
239
+
240
+ let name = action.form.querySelector('input[key="name"]');
241
+ if (name)
242
+ name = await name.getValue()
243
+
244
+ let from = action.form.querySelector('input[key="from"]');
245
+ if (from)
246
+ from = await from.getValue()
247
+
248
+ let origin = action.form.querySelector('input[key="origin"]');
249
+ if (origin)
250
+ origin = await origin.getValue() || window.location.origin
251
+
252
+ let hostname = action.form.querySelector('input[key="hostname"]');
253
+ if (hostname)
254
+ hostname = await hostname.getValue() || window.location.hostname
255
+
256
+ let path = action.form.querySelector('input[key="path"]');
257
+ if (path)
258
+ path = await path.getValue()
259
+
260
+ let request = {
261
+ method: 'inviteUser',
262
+ name,
263
+ email,
264
+ from,
265
+ origin,
266
+ hostname,
267
+ path
268
+ }
269
+
270
+ Crud.socket.send(request).then((response) => {
271
+ if (response.success)
272
+ document.dispatchEvent(new CustomEvent('inviteUser'));
273
+
274
+ render({
275
+ selector: "[template*='inviteUser']",
276
+ data: [{
277
+ type: 'inviteUser',
278
+ message: response.message,
279
+ success: response.success
280
+ }]
281
+ });
282
+
283
+ })
284
+ },
285
+
286
+ acceptInvite: async function (action) {
287
+ let data = {
288
+ method: 'acceptInvite',
289
+ success: false
290
+ }
291
+
292
+ let token = action.form.querySelector('input[key="token"]');
293
+ if (token)
294
+ data.token = await token.getValue()
295
+ let user_id = action.form.querySelector('input[key="_id"]');
296
+ if (user_id)
297
+ data.user_id = await user_id.getValue()
298
+ let email = action.form.querySelector('input[key="email"]');
299
+ if (email)
300
+ data.email = await email.getValue()
301
+
302
+ if (data.token && data.user_id) {
303
+ data = await Crud.socket.send(data)
304
+ } else {
305
+ data.message = 'Invitation failed'
306
+ }
307
+
308
+ if (data.success)
309
+ document.dispatchEvent(new CustomEvent('acceptInvite'));
310
+ render({
311
+ selector: "[template*='acceptInvite']",
312
+ data: [{
313
+ type: 'acceptInvite',
314
+ message: data.message,
315
+ success: data.success,
316
+ }]
317
+ });
318
+ },
319
+
320
+
230
321
  forgotPassword: async function (action) {
231
322
  let email = action.form.querySelector('input[key="email"]');
232
323
  if (!email)
@@ -330,6 +421,20 @@ Actions.init([
330
421
  CoCreateUser.signOut(action);
331
422
  }
332
423
  },
424
+ {
425
+ name: "inviteUser",
426
+ endEvent: "inviteUser",
427
+ callback: (action) => {
428
+ CoCreateUser.inviteUser(action);
429
+ }
430
+ },
431
+ {
432
+ name: "acceptInvite",
433
+ endEvent: "acceptInvite",
434
+ callback: (action) => {
435
+ CoCreateUser.acceptInvite(action);
436
+ }
437
+ },
333
438
  {
334
439
  name: "forgotPassword",
335
440
  endEvent: "forgotPassword",
package/src/server.js CHANGED
@@ -11,6 +11,8 @@ class CoCreateUser {
11
11
  this.wsManager.on('signIn', (data) => this.signIn(data))
12
12
  this.wsManager.on('userStatus', (data) => this.userStatus(data))
13
13
  this.wsManager.on('checkSession', (data) => this.checkSession(data))
14
+ this.wsManager.on('inviteUser', (data) => this.inviteUser(data))
15
+ this.wsManager.on('acceptInvite', (data) => this.acceptInvite(data))
14
16
  this.wsManager.on('forgotPassword', (data) => this.forgotPassword(data))
15
17
  this.wsManager.on('resetPassword', (data) => this.resetPassword(data))
16
18
  }
@@ -153,6 +155,134 @@ class CoCreateUser {
153
155
  }
154
156
  }
155
157
 
158
+ async inviteUser(data) {
159
+ try {
160
+ const inviteId = this.crud.ObjectId().toString()
161
+ let uid = data.uid
162
+ delete data.uid
163
+
164
+ data.method = 'object.update'
165
+ data.array = "users"
166
+ data.object = { _id: data.user_id, '$addToSet.invitations': inviteId, '$addToSet.members': data.email }
167
+
168
+ data = await this.crud.send(data)
169
+
170
+ let htmlBody = `
171
+ <html>
172
+ <head>
173
+ <title>Welcome to Yellow Oracle!</title>
174
+ </head>
175
+ <body>
176
+ <p>Hello,</p>
177
+
178
+ <p>You have been invited to join ${data.name} on Yellow Oracle.</p>
179
+
180
+ <p><a href="${data.origin}${data.path}?email=${data.email}&token=${inviteId}&user_id=${data.user_id}&name=${data.name}" style="color: #ffffff; background-color: #FFD700; padding: 10px 20px; text-decoration: none; border-radius: 5px;">Accept Your Invitation</a></p>
181
+
182
+ <p>Please note, this invitation link will expire in 48 hours. We encourage you to accept it soon to begin your journey with ${data.name} on Yellow Oracle.</p>
183
+
184
+ <p>If the button above doesn't work, you can copy and paste the following URL into your web browser:</p>
185
+ <p><a href="${data.origin}${data.path}?email=${data.email}&token=${inviteId}&user_id=${data.user_id}&name=${data.name}">${data.origin}${data.path}?email=${data.email}&token=${inviteId}&user_id=${data.user_id}&name=${data.name}</a></p>
186
+
187
+ <p>If you received this invitation by mistake or have any questions, please don't hesitate to get in touch with our support team at <a href="mailto:support@${data.hostname}">support@${data.hostname}</a>.</p>
188
+
189
+ <p>We look forward to welcoming you to ${data.name}'s Yellow Oracle account!</p>
190
+
191
+ </body>
192
+ </html>
193
+ `;
194
+
195
+ let email = {
196
+ method: 'postmark.sendEmail',
197
+ host: data.host,
198
+ postmark: {
199
+ "From": data.from,
200
+ "To": data.email,
201
+ "Subject": `${data.name} has invited you to join them on Yellow Oracle`,
202
+ "HtmlBody": htmlBody,
203
+ "TextBody": "Hello, \n\nWe received a request to reset the password for your account.If you did not make this request, please ignore this email.Otherwise, you can reset your password by copying and pasting the following link into your browser: https://example.com/reset-password\n\nThis link will expire in 24 hours for your security.\n\nNeed more help? Our support team is here for you at support@example.com.\n\nThank you for using our services!\n\nBest regards,\nThe [Your Company] Team",
204
+ "MessageStream": "outbound"
205
+ },
206
+ organization_id: data.organization_id
207
+ }
208
+
209
+ // TODO: wsManager.emit('postmark', email) needs to await response
210
+ this.wsManager.emit('postmark', email);
211
+
212
+ let response = {
213
+ socket: data.socket,
214
+ host: data.host,
215
+ method: 'inviteUser',
216
+ success: true,
217
+ message: "Succesfully sent invite",
218
+ organization_id: data.organization_id,
219
+ uid
220
+ }
221
+
222
+ this.wsManager.send(response)
223
+
224
+ } catch (error) {
225
+ data.error = error
226
+ this.wsManager.send(data)
227
+
228
+ console.log('Invite User failed', error);
229
+ }
230
+ }
231
+
232
+ async acceptInvite(data) {
233
+ const self = this;
234
+ try {
235
+ if (!data.token || !data.user_id) {
236
+ // TODO: handle error
237
+ return
238
+ }
239
+
240
+ let socket = data.socket
241
+ delete data.socket
242
+ let uid = data.uid
243
+ delete data.uid
244
+
245
+ data.method = 'object.update'
246
+ data.array = "users"
247
+ data.object = { '$pull.invitations': data.token, '$pull.members': data.email }
248
+ data.$filter = {
249
+ query: { invitations: { $in: [data.token] }, members: { $in: [data.email] } },
250
+ limit: 1
251
+ }
252
+
253
+ data = await this.crud.send(data)
254
+
255
+ let response = {
256
+ socket,
257
+ host: data.host,
258
+ method: 'acceptInvite',
259
+ success: false,
260
+ message: "Token is invalid or has expired",
261
+ organization_id: data.organization_id,
262
+ uid
263
+ }
264
+
265
+ for (let object of data.object) {
266
+ if (object._id) {
267
+ delete data.$filter
268
+ data.socket = socket
269
+ data.object = { _id: object._id, '$addToSet.members': data.user_id }
270
+ data = await this.crud.send(data)
271
+ this.crud.send({ method: 'object.update', array: 'users', object: { _id: data.user_id, memberAccount: object._id, subscription: '6571fe530c48ef6970900a82' } })
272
+ response.success = true
273
+ response.message = "Invite Accepted"
274
+ break
275
+ }
276
+ }
277
+
278
+ self.wsManager.send(response)
279
+
280
+ } catch (error) {
281
+ console.log("Password reset failed", error);
282
+ }
283
+ }
284
+
285
+
156
286
  async forgotPassword(data) {
157
287
  const self = this;
158
288
  try {
@@ -233,7 +363,7 @@ class CoCreateUser {
233
363
  })
234
364
 
235
365
  } catch (error) {
236
- console.log('signIn failed', error);
366
+ console.log('Forgot Password failed', error);
237
367
  }
238
368
  }
239
369