@cocreate/users 1.33.1 → 1.34.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,34 @@
1
+ ## [1.34.1](https://github.com/CoCreate-app/CoCreate-users/compare/v1.34.0...v1.34.1) (2024-01-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * render response ([33054b5](https://github.com/CoCreate-app/CoCreate-users/commit/33054b5164c370c50692a053d4bc789031208828))
7
+
8
+ # [1.34.0](https://github.com/CoCreate-app/CoCreate-users/compare/v1.33.1...v1.34.0) (2024-01-30)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * add host when sending email to access environments ([8681adc](https://github.com/CoCreate-app/CoCreate-users/commit/8681adc38970838d0e958d40bc07951ce6edb67c))
14
+ * checkSession ([53bb1a9](https://github.com/CoCreate-app/CoCreate-users/commit/53bb1a9b96da627f52446d7273f3af53f7640e2f))
15
+ * checkSession response ([a254266](https://github.com/CoCreate-app/CoCreate-users/commit/a254266a8ef7cdb97d41a635c971f0330d913ac9))
16
+ * forgotPassword email links ([20fc214](https://github.com/CoCreate-app/CoCreate-users/commit/20fc214db4635a9aaece1169fb1364efb8d0ff73))
17
+ * handling of host, origin and path ([78c8e42](https://github.com/CoCreate-app/CoCreate-users/commit/78c8e42285fb2536e003cd7ba98380055f4152b5))
18
+ * if signin success add user_id to socket ([bc64c10](https://github.com/CoCreate-app/CoCreate-users/commit/bc64c10adabb6ac39157eeb40e98786ca594f70f))
19
+ * remove recoveryId once used ([09e5f66](https://github.com/CoCreate-app/CoCreate-users/commit/09e5f66c1e33f884d84960f199f1f7a47995ef53))
20
+ * removed company name ([a3b97c0](https://github.com/CoCreate-app/CoCreate-users/commit/a3b97c0c7aaf9cc205f9aee160c606b5ddbc660f))
21
+ * render forgotPassword response ([77d6482](https://github.com/CoCreate-app/CoCreate-users/commit/77d64821a0a3ce6684db350c9e9c2a2432d4f00a))
22
+ * typo ([d091f69](https://github.com/CoCreate-app/CoCreate-users/commit/d091f69a4f936919741dc070aa438e7ba5471830))
23
+ * update render data to array ([b78dd53](https://github.com/CoCreate-app/CoCreate-users/commit/b78dd53481ccd0827e03e0af2de1c1e28c9316d1))
24
+
25
+
26
+ ### Features
27
+
28
+ * checkSession ([a7b000a](https://github.com/CoCreate-app/CoCreate-users/commit/a7b000a0422cd2980cc9f44eb366103ce346b64c))
29
+ * forgotPassword and resetPasword handling ([d5fcca6](https://github.com/CoCreate-app/CoCreate-users/commit/d5fcca62fa2f0588a8b0799f59362719e230b1d2))
30
+ * handle session attribute ([65bde0e](https://github.com/CoCreate-app/CoCreate-users/commit/65bde0e6fe7a41563b30b4fcd86b60b7fc0acfea))
31
+
1
32
  ## [1.33.1](https://github.com/CoCreate-app/CoCreate-users/compare/v1.33.0...v1.33.1) (2024-01-17)
2
33
 
3
34
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/users",
3
- "version": "1.33.1",
3
+ "version": "1.34.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
@@ -4,6 +4,7 @@ import Actions from '@cocreate/actions';
4
4
  import Elements from '@cocreate/elements';
5
5
  import { render } from '@cocreate/render';
6
6
  import '@cocreate/element-prototype';
7
+ import Observer from '@cocreate/observer'
7
8
  import './index.css';
8
9
 
9
10
  // TODO: Replace with @cocreate/config
@@ -63,11 +64,11 @@ const CoCreateUser = {
63
64
 
64
65
  render({
65
66
  selector: "[template*='signUp']",
66
- data: {
67
+ data: [{
67
68
  type: 'signUp',
68
69
  message: 'Succesfully Signed Up',
69
70
  success: true
70
- }
71
+ }]
71
72
  });
72
73
 
73
74
  document.dispatchEvent(new CustomEvent('signUp', {
@@ -127,6 +128,8 @@ const CoCreateUser = {
127
128
  localStorage.setItem('user_id', user_id);
128
129
  localStorage.setItem("token", token);
129
130
  message = "Successful signIn";
131
+ Crud.socket.user_id = user_id
132
+
130
133
  document.dispatchEvent(new CustomEvent('signIn', {
131
134
  detail: {}
132
135
  }));
@@ -136,12 +139,12 @@ const CoCreateUser = {
136
139
 
137
140
  render({
138
141
  selector: "[template*='signIn']",
139
- data: {
142
+ data: [{
140
143
  type: 'signIn',
141
144
  status,
142
145
  message,
143
146
  success
144
- }
147
+ }]
145
148
  });
146
149
  },
147
150
 
@@ -152,11 +155,11 @@ const CoCreateUser = {
152
155
 
153
156
  render({
154
157
  selector: "[template*='signOut']",
155
- data: {
158
+ data: [{
156
159
  type: 'signOut',
157
160
  message: 'Succesfully logged out',
158
161
  success: true
159
- }
162
+ }]
160
163
  });
161
164
 
162
165
  // TODO: replace with Custom event system
@@ -176,12 +179,9 @@ const CoCreateUser = {
176
179
  },
177
180
 
178
181
  redirect: (data) => {
179
- if (data.user_id !== Crud.socket.user_id || data.clientId !== Crud.socket.clientId)
182
+ if (data.user_id && data.user_id !== Crud.socket.user_id || data.clientId && data.clientId !== Crud.socket.clientId)
180
183
  return
181
- // if (data.user_id && data.user_id !== Crud.socket.user_id)
182
- // return
183
- // if (!data.user_id && data.clientId !== Crud.socket.clientId)
184
- // return
184
+
185
185
  if (data.userStatus == 'on' || data.userStatus == 'idle') {
186
186
  let redirectTag = document.querySelector('[session="true"]');
187
187
 
@@ -191,6 +191,7 @@ const CoCreateUser = {
191
191
  document.location.href = redirectLink;
192
192
  }
193
193
  }
194
+
194
195
  } else if (data.userStatus == 'off') {
195
196
  let redirectTag = document.querySelector('[session="false"]');
196
197
 
@@ -204,6 +205,11 @@ const CoCreateUser = {
204
205
  }
205
206
  }
206
207
 
208
+ if (data.userStatus) {
209
+ let sessionElements = document.querySelectorAll('[session]:not([href])');
210
+ for (let i = 0; i < sessionElements.length; i++)
211
+ sessionElements[i].setAttribute('session', data.userStatus)
212
+ }
207
213
  },
208
214
 
209
215
  initSession: () => {
@@ -221,8 +227,84 @@ const CoCreateUser = {
221
227
  },
222
228
 
223
229
  // TODO: updatePassword()
224
- updatePassword: function (btn) {
225
- this.signIn(btn);
230
+ forgotPassword: async function (action) {
231
+ let email = action.form.querySelector('input[key="email"]');
232
+ if (!email)
233
+ return
234
+ else
235
+ email = await email.getValue()
236
+
237
+ let from = action.form.querySelector('input[key="from"]');
238
+ if (from)
239
+ from = await from.getValue()
240
+
241
+ let origin = action.form.querySelector('input[key="origin"]');
242
+ if (origin)
243
+ origin = await origin.getValue() || window.location.origin
244
+
245
+ let hostname = action.form.querySelector('input[key="origin"]');
246
+ if (hostname)
247
+ hostname = await hostname.getValue() || window.location.hostname
248
+
249
+ let path = action.form.querySelector('input[key="path"]');
250
+ if (path)
251
+ path = await path.getValue()
252
+
253
+ let request = {
254
+ method: 'forgotPassword',
255
+ email,
256
+ from,
257
+ origin,
258
+ hostname,
259
+ path
260
+ }
261
+
262
+ Crud.socket.send(request).then((response) => {
263
+ console.log('forgot password', response)
264
+ render({
265
+ selector: "[template*='forgotPassword']",
266
+ data: [{
267
+ type: 'forgotPassword',
268
+ message: response.message,
269
+ success: response.success
270
+ }]
271
+ });
272
+
273
+ })
274
+ },
275
+
276
+ resetPassword: async function (action) {
277
+ let data = {
278
+ method: 'resetPassword'
279
+ }
280
+ let email = action.form.querySelector('input[key="email"]');
281
+ if (email)
282
+ data.email = await email.getValue()
283
+ else return
284
+
285
+ let password = action.form.querySelector('input[key="password"]');
286
+ if (password)
287
+ data.password = await password.getValue()
288
+ else return
289
+
290
+ let token = action.form.querySelector('input[key="token"]');
291
+ if (token)
292
+ data.token = await token.getValue()
293
+ else return
294
+
295
+ Crud.socket.send(data).then((data) => {
296
+ if (data.success)
297
+ document.dispatchEvent(new CustomEvent('resetPassword'));
298
+ else
299
+ render({
300
+ selector: "[template*='resetPassword']",
301
+ data: [{
302
+ type: 'resetPassword',
303
+ message: data.message,
304
+ success: data.success,
305
+ }]
306
+ });
307
+ })
226
308
  }
227
309
  };
228
310
 
@@ -247,9 +329,36 @@ Actions.init([
247
329
  callback: (action) => {
248
330
  CoCreateUser.signOut(action);
249
331
  }
332
+ },
333
+ {
334
+ name: "forgotPassword",
335
+ endEvent: "forgotPassword",
336
+ callback: (action) => {
337
+ CoCreateUser.forgotPassword(action);
338
+ }
339
+ },
340
+ {
341
+ name: "resetPassword",
342
+ endEvent: "resetPassword",
343
+ callback: (action) => {
344
+ CoCreateUser.resetPassword(action);
345
+ }
250
346
  }
251
347
  ]);
252
348
 
349
+ Observer.init({
350
+ name: 'CoCreateElementsRemovedNodes',
351
+ observe: ['addedNodes'],
352
+ target: '[session]',
353
+ callback: () => {
354
+ Crud.socket.send({
355
+ method: 'checkSession',
356
+ broadcast: false,
357
+ broadcastBrowser: false
358
+ });
359
+ }
360
+ });
361
+
253
362
  CoCreateUser.init();
254
363
 
255
364
  export default CoCreateUser;
package/src/server.js CHANGED
@@ -10,6 +10,9 @@ class CoCreateUser {
10
10
  this.wsManager.on('signUp', (data) => this.signUp(data));
11
11
  this.wsManager.on('signIn', (data) => this.signIn(data))
12
12
  this.wsManager.on('userStatus', (data) => this.userStatus(data))
13
+ this.wsManager.on('checkSession', (data) => this.checkSession(data))
14
+ this.wsManager.on('forgotPassword', (data) => this.forgotPassword(data))
15
+ this.wsManager.on('resetPassword', (data) => this.resetPassword(data))
13
16
  }
14
17
  }
15
18
 
@@ -136,6 +139,142 @@ class CoCreateUser {
136
139
  console.log('userStatus error')
137
140
  }
138
141
  }
142
+
143
+ async checkSession(data) {
144
+ try {
145
+ if (!data.socket.user_id) {
146
+ data.method = 'updateUserStatus'
147
+ data.userStatus = 'off'
148
+
149
+ this.wsManager.send(data)
150
+ }
151
+ } catch (error) {
152
+ console.log('checkSession error')
153
+ }
154
+ }
155
+
156
+ async forgotPassword(data) {
157
+ const self = this;
158
+ try {
159
+ const recoveryId = this.crud.ObjectId().toString()
160
+ let socket = data.socket
161
+ delete data.socket
162
+
163
+ data.method = 'object.update'
164
+ data.array = "keys"
165
+ data.object = { recoveryId }
166
+ data.$filter = {
167
+ query: { email: data.email },
168
+ limit: 1
169
+ }
170
+
171
+ this.crud.send(data).then(async (data) => {
172
+ let response = {
173
+ socket,
174
+ host: data.host,
175
+ method: 'forgotPassword',
176
+ success: false,
177
+ message: "Email does not exist",
178
+ organization_id: data.organization_id,
179
+ uid: data.uid
180
+ }
181
+
182
+ for (let object of data.object) {
183
+ if (object._id) {
184
+ // TODO: sendEmail
185
+ response.success = true
186
+ response.message = "Email Sent"
187
+ let htmlBody = `
188
+ <html>
189
+ <head>
190
+ <title>Reset Your Password</title>
191
+ </head>
192
+ <body>
193
+ <p>Hello,</p>
194
+
195
+ <p>We 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 using the link below.</p>
196
+
197
+ <p><a href="${data.origin}${data.path}?email=${data.email}&token=${recoveryId}&recoveyId=${recoveryId}" style="color: #ffffff; background-color: #007bff; padding: 10px 20px; text-decoration: none; border-radius: 5px;">Reset My Password</a></p>
198
+
199
+ <p>This link will expire in 24 hours for your security.</p>
200
+
201
+ <p>If you're having trouble with the button above, copy and paste the URL below into your web browser:</p>
202
+ <p><a href="${data.origin}${data.path}?email=${data.email}&token=${recoveryId}&recoveyId=${recoveryId}"">${data.origin}${data.path}?email=${data.email}&token=${recoveryId}&recoveyId=${recoveryId}"</a></p>
203
+
204
+ <p>Need more help? Our support team is here for you. Contact us at <a href="mailto:support@${data.hostname}">support@${data.hostname}</a>.</p>
205
+
206
+ <p>Thank you for using our services!</p>
207
+
208
+ </body>
209
+ </html>
210
+ `
211
+ let email = {
212
+ method: 'postmark.sendEmail',
213
+ host: data.host,
214
+ postmark: {
215
+ "From": data.from,
216
+ "To": data.email,
217
+ "Subject": "Reset Your Password Easily",
218
+ "HtmlBody": htmlBody,
219
+ "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",
220
+ "MessageStream": "outbound"
221
+ },
222
+ organization_id: data.organization_id
223
+ }
224
+
225
+ self.wsManager.emit('postmark', email);
226
+
227
+ break
228
+ }
229
+ }
230
+
231
+ self.wsManager.send(response)
232
+ })
233
+
234
+ } catch (error) {
235
+ console.log('signIn failed', error);
236
+ }
237
+ }
238
+
239
+ async resetPassword(data) {
240
+ const self = this;
241
+ try {
242
+ if (!data.email || !data.password || !data.token)
243
+ return
244
+
245
+ data.method = 'object.update'
246
+ data.array = "keys"
247
+ data.object = { password: data.password, recoveryId: "" }
248
+ data.$filter = {
249
+ query: { email: data.email, recoveryId: data.token },
250
+ limit: 1
251
+ }
252
+
253
+ this.crud.send(data).then(async (data) => {
254
+ let response = {
255
+ socket: data.socket,
256
+ host: data.host,
257
+ method: 'resetPassword',
258
+ success: false,
259
+ message: "Token is invalid or has expired",
260
+ organization_id: data.organization_id,
261
+ uid: data.uid
262
+ }
263
+
264
+ for (let object of data.object) {
265
+ if (object._id) {
266
+ response.success = true
267
+ response.message = "Password reset succesfull"
268
+ break
269
+ }
270
+ }
271
+
272
+ self.wsManager.send(response)
273
+ })
274
+ } catch (error) {
275
+ console.log("Password reset failed", error);
276
+ }
277
+ }
139
278
  }
140
279
 
141
280
  module.exports = CoCreateUser;