@social-mail/social-mail-web-server 1.4.819 → 1.4.821

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.
Files changed (52) hide show
  1. package/dist/common/globalEnv.d.ts +5 -0
  2. package/dist/common/globalEnv.d.ts.map +1 -1
  3. package/dist/common/globalEnv.js +5 -0
  4. package/dist/common/globalEnv.js.map +1 -1
  5. package/dist/server/model/entities/LoginSession.d.ts +1 -5
  6. package/dist/server/model/entities/LoginSession.d.ts.map +1 -1
  7. package/dist/server/model/entities/LoginSession.js +1 -1
  8. package/dist/server/model/entities/LoginSession.js.map +1 -1
  9. package/dist/server/model/entities/Mailbox.d.ts +1 -0
  10. package/dist/server/model/entities/Mailbox.d.ts.map +1 -1
  11. package/dist/server/model/entities/Mailbox.js +4 -0
  12. package/dist/server/model/entities/Mailbox.js.map +1 -1
  13. package/dist/server/model/entities/MailboxContact.d.ts.map +1 -1
  14. package/dist/server/model/entities/MailboxContact.js +4 -1
  15. package/dist/server/model/entities/MailboxContact.js.map +1 -1
  16. package/dist/server/model/entities/MailboxContactEmail.d.ts.map +1 -1
  17. package/dist/server/model/entities/MailboxContactEmail.js +4 -1
  18. package/dist/server/model/entities/MailboxContactEmail.js.map +1 -1
  19. package/dist/server/model/entities/MailboxEmail.d.ts.map +1 -1
  20. package/dist/server/model/entities/MailboxEmail.js +4 -1
  21. package/dist/server/model/entities/MailboxEmail.js.map +1 -1
  22. package/dist/server/model/events/AccessTokenEvents.d.ts.map +1 -1
  23. package/dist/server/model/events/AccessTokenEvents.js +1 -0
  24. package/dist/server/model/events/AccessTokenEvents.js.map +1 -1
  25. package/dist/server/model/events/LoginSessionEvents.d.ts.map +1 -1
  26. package/dist/server/model/events/LoginSessionEvents.js +4 -5
  27. package/dist/server/model/events/LoginSessionEvents.js.map +1 -1
  28. package/dist/server/model/events/MailboxEvents.d.ts +1 -0
  29. package/dist/server/model/events/MailboxEvents.d.ts.map +1 -1
  30. package/dist/server/model/events/MailboxEvents.js +27 -0
  31. package/dist/server/model/events/MailboxEvents.js.map +1 -1
  32. package/dist/server/model/events/UserEvents.d.ts +1 -0
  33. package/dist/server/model/events/UserEvents.d.ts.map +1 -1
  34. package/dist/server/model/events/UserEvents.js +6 -0
  35. package/dist/server/model/events/UserEvents.js.map +1 -1
  36. package/dist/server/services/external-otp-in/ExternalOtpInService.d.ts +10 -0
  37. package/dist/server/services/external-otp-in/ExternalOtpInService.d.ts.map +1 -0
  38. package/dist/server/services/external-otp-in/ExternalOtpInService.js +41 -0
  39. package/dist/server/services/external-otp-in/ExternalOtpInService.js.map +1 -0
  40. package/dist/tsconfig.tsbuildinfo +1 -1
  41. package/package.json +1 -1
  42. package/src/common/globalEnv.ts +5 -0
  43. package/src/server/model/entities/LoginSession.ts +1 -1
  44. package/src/server/model/entities/Mailbox.ts +3 -0
  45. package/src/server/model/entities/MailboxContact.ts +4 -1
  46. package/src/server/model/entities/MailboxContactEmail.ts +4 -1
  47. package/src/server/model/entities/MailboxEmail.ts +4 -1
  48. package/src/server/model/events/AccessTokenEvents.ts +2 -0
  49. package/src/server/model/events/LoginSessionEvents.ts +4 -3
  50. package/src/server/model/events/MailboxEvents.ts +41 -0
  51. package/src/server/model/events/UserEvents.ts +9 -0
  52. package/src/server/services/external-otp-in/ExternalOtpInService.ts +36 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-web-server",
3
- "version": "1.4.819",
3
+ "version": "1.4.821",
4
4
  "description": "## Phase 1",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -27,6 +27,11 @@ export const globalEnv = {
27
27
  wildcardDomain: process.env.SOCIAL_MAIL_WILDCARD_DOMAIN,
28
28
  name: process.env.SOCIAL_MAIL_NAME || "Social Mail",
29
29
  secretKey: process.env.SOCIAL_MAIL_SECRET_KEY,
30
+ otpIn:{
31
+ host: process.env.SOCIAL_MAIL_OTP_IN_HOST,
32
+ key: process.env.SOCIAL_MAIL_OTP_IN_KEY,
33
+ secret: process.env.SOCIAL_MAIL_OTP_IN_SECRET,
34
+ },
30
35
  port,
31
36
  serverID: process.env.SOCIAL_MAIL_SERVER_ID,
32
37
  parentApiToken: process.env.SOCIAL_MAIL_PARENT_API_TOKEN,
@@ -99,7 +99,7 @@ export default class LoginSession {
99
99
  public oneTimePassword: string;
100
100
 
101
101
  @JsonProperty({ help: "SMS URL to Display"})
102
- public smsConfig: { prefix: string, code: string, url: string }[];
102
+ public smsConfig: any;
103
103
 
104
104
  public user: User;
105
105
 
@@ -165,6 +165,9 @@ export default class Mailbox {
165
165
  @JsonProperty()
166
166
  public notify: boolean;
167
167
 
168
+ @JsonProperty()
169
+ public deleteVerificationID: string;
170
+
168
171
  public channelConfig: ChannelConfig;
169
172
 
170
173
  public domain: HostedDomain;
@@ -45,7 +45,10 @@ export default class MailboxContact {
45
45
  @Column({ key: true, dataType: "BigInt", order: 1 })
46
46
  @RelateTo(Mailbox,{
47
47
  property: (mt) => mt.mailbox,
48
- inverseProperty: (mb) => mb.mailboxContacts
48
+ inverseProperty: (mb) => mb.mailboxContacts,
49
+ foreignKeyConstraint: {
50
+ cascade: "restrict"
51
+ }
49
52
  })
50
53
  public mailboxID: number;
51
54
 
@@ -26,7 +26,10 @@ export default class MailboxContactEmail {
26
26
  @Column({ key: true, dataType: "BigInt", order: 1})
27
27
  @RelateTo(Mailbox, {
28
28
  property: (mte) => mte.mailbox,
29
- inverseProperty: (mb) => mb.threadEmails
29
+ inverseProperty: (mb) => mb.threadEmails,
30
+ foreignKeyConstraint: {
31
+ cascade: "restrict"
32
+ }
30
33
  })
31
34
  mailboxID: number;
32
35
 
@@ -10,7 +10,10 @@ export default class MailboxEmail {
10
10
  @Column({ dataType: "BigInt", key: true, order: 1 })
11
11
  @RelateTo(Mailbox, {
12
12
  property: (me) => me.mailbox,
13
- inverseProperty: (m) => m.emails
13
+ inverseProperty: (m) => m.emails,
14
+ foreignKeyConstraint: {
15
+ cascade: "restrict"
16
+ }
14
17
  })
15
18
  mailboxID: number;
16
19
 
@@ -11,6 +11,8 @@ export default class AccessTokenEvents extends AuthenticatedEvents<AccessToken>
11
11
  this.sessionUser.ensureLoggedIn();
12
12
  }
13
13
 
14
+ entity.userID ??= this.sessionUser.userID;
15
+
14
16
  entity.secret = "sm-at-" + randomUUID().replaceAll("-", "");
15
17
  entity.displaySecret = entity.secret;
16
18
  }
@@ -18,6 +18,7 @@ import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
18
18
  import { randomUUID } from "crypto";
19
19
  import { AppStringHelper } from "../../../common/AppStringHelper.js";
20
20
  import IncomingSmsService from "../../services/incoming-sms/IncomingSmsService.js";
21
+ import ExternalOtpInService from "../../services/external-otp-in/ExternalOtpInService.js";
21
22
 
22
23
  export default class LoginSessionEvents extends EntityEvents<LoginSession> {
23
24
 
@@ -140,9 +141,9 @@ export default class LoginSessionEvents extends EntityEvents<LoginSession> {
140
141
  .toArray();
141
142
 
142
143
  if (otpIn.length) {
143
- const code = entity.smsToken = AppStringHelper.last(DateTime.now.msSinceEpoch.toString(), 6);
144
- const idsCodes = otpIn.map((x) => x.isdCode.startsWith("+") ? x.isdCode : "+" + x.isdCode );
145
- entity.smsConfig = await ServiceProvider.resolve(this, IncomingSmsService).prepareCode(code, ... idsCodes);
144
+ const idsCodes = otpIn.map((x) => x.phoneNumber );
145
+ entity.smsConfig = await ServiceProvider.resolve(this, ExternalOtpInService).create(idsCodes);
146
+ entity.smsToken = entity.smsConfig.id;
146
147
  }
147
148
 
148
149
  return;
@@ -13,6 +13,7 @@ import External from "@entity-access/server-pages/dist/decorators/External.js";
13
13
  import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
14
14
  import Page from "@entity-access/server-pages/dist/Page.js";
15
15
  import { Prepare } from "@entity-access/server-pages/dist/decorators/Prepare.js";
16
+ import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
16
17
 
17
18
  export default class MailboxEvents extends AuthenticatedEvents<Mailbox> {
18
19
 
@@ -166,4 +167,44 @@ export default class MailboxEvents extends AuthenticatedEvents<Mailbox> {
166
167
  }
167
168
 
168
169
  }
170
+
171
+ async beforeDelete(entity: Mailbox, entry: ChangeEntry<Mailbox>) {
172
+ this.sessionUser.ensureIsAdmin();
173
+
174
+ const{ db } = this;
175
+
176
+ // if (!entity.deleteVerificationID) {
177
+ // throw new EntityAccessError(`Delete operation not authorized`);
178
+ // }
179
+
180
+ // const [id, accessCode] = entity.deleteVerificationID.split(":") as any[];
181
+
182
+ // const v = await db.verificationTokens.statements.select({} , { verificationID: id, accessCode });
183
+ // if (!v) {
184
+ // throw new EntityAccessError(`Delete operation not authorized`);
185
+ // }
186
+
187
+ await db.fileContents.asQuery()
188
+ .where(entity, (p) => (x) => x.appFiles.some((a) => a.email.mailboxes.some((m) => m.mailboxID === p.mailboxID)))
189
+ .update(void 0, (p) => (x) => ({
190
+ deleted: true
191
+ }));
192
+
193
+
194
+ await db.appFiles.asQuery()
195
+ .delete(entity, (p) => (x) => x.email.mailboxes.some((m) => m.mailboxID === p.mailboxID));
196
+
197
+
198
+ await db.emails.asQuery()
199
+ .delete(entity, (p) => (x) => x.mailboxes.some((m) => m.mailboxID === p.mailboxID));
200
+
201
+ await db.mailboxContactEmails.asQuery()
202
+ .delete(entity, (p) => (x) => x.mailboxID === p.mailboxID);
203
+
204
+ await db.mailboxContactTags.asQuery()
205
+ .delete(entity, (p) => (x) => x.mailboxID === p.mailboxID);
206
+
207
+ await db.mailboxEmails.asQuery()
208
+ .delete(entity, (p) => (x) => x.mailboxID === p.mailboxID);
209
+ }
169
210
  }
@@ -203,10 +203,19 @@ export default class UserEvents extends AuthenticatedEvents<User> {
203
203
  }
204
204
  }
205
205
 
206
+ async beforeDelete(entity: User, entry: ChangeEntry<User>) {
207
+ this.sessionUser.ensureIsAdmin();
208
+
209
+ const { db } = this;
210
+ await db.contactPhones.asQuery().delete(entity, (p) => (x) => x.contact.userID === p.userID);
211
+ await db.contacts.asQuery().delete(entity, (p) => (x) => x.userID === p.userID);
212
+ }
213
+
206
214
  private updatePassword(entity: User, password: string) {
207
215
  const passwordSalt = this.cryptoService.generateSalt();
208
216
  entity.passwordSalt = passwordSalt;
209
217
  entity.passwordHash = this.cryptoService.hash(entity.passwordSalt, password);
210
218
  }
211
219
 
220
+
212
221
  }
@@ -0,0 +1,36 @@
1
+ import { RegisterSingleton } from "@entity-access/entity-access/dist/di/di.js";
2
+ import { globalEnv } from "../../../common/globalEnv.js";
3
+
4
+ const headers = {
5
+ authorization: `basic ${Buffer.from(`${globalEnv.otpIn.key}:${globalEnv.otpIn.secret}`).toString("base64")}`
6
+ };
7
+
8
+ const postHeaders = {
9
+ ... headers,
10
+ "content-type": "application/json",
11
+ };
12
+
13
+ @RegisterSingleton
14
+ export default class ExternalOtpInService {
15
+
16
+ async create(phoneNumbers: string[]) {
17
+ const rs = await fetch(`https://${globalEnv.otpIn.host}/api/otp-in/create`, {
18
+ method: "POST",
19
+ headers: postHeaders,
20
+ body: JSON.stringify({
21
+ phoneNumbers
22
+ })
23
+ });
24
+ const { id, ui } = await rs.json();
25
+ return { id, ui };
26
+ }
27
+
28
+ async get(id) {
29
+ const rs = await fetch(`https://${globalEnv.otpIn.host}/api/otp-in/get/${id}`, {
30
+ method: "GET",
31
+ headers
32
+ });
33
+ const { success } = await rs.json();
34
+ return { success };
35
+ }
36
+ }