@social-mail/social-mail-web-server 1.5.49 → 1.5.50

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 (45) hide show
  1. package/dist/server/model/SocialMailContext.d.ts +2 -0
  2. package/dist/server/model/SocialMailContext.d.ts.map +1 -1
  3. package/dist/server/model/SocialMailContext.js +2 -0
  4. package/dist/server/model/SocialMailContext.js.map +1 -1
  5. package/dist/server/model/SocialMailContextEvents.d.ts.map +1 -1
  6. package/dist/server/model/SocialMailContextEvents.js +3 -0
  7. package/dist/server/model/SocialMailContextEvents.js.map +1 -1
  8. package/dist/server/model/entities/EmailAddress.d.ts +2 -0
  9. package/dist/server/model/entities/EmailAddress.d.ts.map +1 -1
  10. package/dist/server/model/entities/EmailAddress.js.map +1 -1
  11. package/dist/server/model/entities/EmailAddressName.d.ts +19 -0
  12. package/dist/server/model/entities/EmailAddressName.d.ts.map +1 -0
  13. package/dist/server/model/entities/EmailAddressName.js +47 -0
  14. package/dist/server/model/entities/EmailAddressName.js.map +1 -0
  15. package/dist/server/model/entities/Tag.d.ts +2 -0
  16. package/dist/server/model/entities/Tag.d.ts.map +1 -1
  17. package/dist/server/model/entities/Tag.js.map +1 -1
  18. package/dist/server/model/events/EmailAddressNameEvents.d.ts +7 -0
  19. package/dist/server/model/events/EmailAddressNameEvents.d.ts.map +1 -0
  20. package/dist/server/model/events/EmailAddressNameEvents.js +10 -0
  21. package/dist/server/model/events/EmailAddressNameEvents.js.map +1 -0
  22. package/dist/server/seed/ui/seed-ui.js +1 -1
  23. package/dist/server/services/EmailAddressService.d.ts.map +1 -1
  24. package/dist/server/services/EmailAddressService.js +10 -1
  25. package/dist/server/services/EmailAddressService.js.map +1 -1
  26. package/dist/server/workflows/email-address/UpdateEmailAddressNameWorkflow.d.ts +11 -0
  27. package/dist/server/workflows/email-address/UpdateEmailAddressNameWorkflow.d.ts.map +1 -0
  28. package/dist/server/workflows/email-address/UpdateEmailAddressNameWorkflow.js +44 -0
  29. package/dist/server/workflows/email-address/UpdateEmailAddressNameWorkflow.js.map +1 -0
  30. package/dist/server/workflows/repair/tags/RepairEmailNameTagsWorkflow.d.ts +9 -0
  31. package/dist/server/workflows/repair/tags/RepairEmailNameTagsWorkflow.d.ts.map +1 -0
  32. package/dist/server/workflows/repair/tags/RepairEmailNameTagsWorkflow.js +64 -0
  33. package/dist/server/workflows/repair/tags/RepairEmailNameTagsWorkflow.js.map +1 -0
  34. package/dist/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +1 -1
  36. package/src/server/model/SocialMailContext.ts +3 -0
  37. package/src/server/model/SocialMailContextEvents.ts +3 -0
  38. package/src/server/model/entities/EmailAddress.ts +2 -0
  39. package/src/server/model/entities/EmailAddressName.ts +37 -0
  40. package/src/server/model/entities/Tag.ts +3 -1
  41. package/src/server/model/events/EmailAddressNameEvents.ts +14 -0
  42. package/src/server/seed/ui/seed-ui.ts +1 -1
  43. package/src/server/services/EmailAddressService.ts +13 -1
  44. package/src/server/workflows/email-address/UpdateEmailAddressNameWorkflow.ts +30 -0
  45. package/src/server/workflows/repair/tags/RepairEmailNameTagsWorkflow.ts +57 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-web-server",
3
- "version": "1.5.49",
3
+ "version": "1.5.50",
4
4
  "description": "## Phase 1",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -45,6 +45,7 @@ import IncomingSmsSource from "./entities/IncomingSmsSource.js";
45
45
  import VerificationToken, { VerificationTokenAddress } from "./entities/VerificationToken.js";
46
46
  import MailboxFolder from "./entities/MailboxFolder.js";
47
47
  import HostedZone, { HostedZoneRecord, HostedZoneUser } from "./entities/HostedZone.js";
48
+ import EmailAddressName from "./entities/EmailAddressName.js";
48
49
 
49
50
  @RegisterScoped
50
51
  export default class SocialMailContext extends EntityContext {
@@ -205,6 +206,8 @@ export default class SocialMailContext extends EntityContext {
205
206
 
206
207
  public verificationTokenAddresses = this.model.register(VerificationTokenAddress);
207
208
 
209
+ public emailAddressNames = this.model.register(EmailAddressName);
210
+
208
211
  public tags = this.model.register(Tag);
209
212
 
210
213
  }
@@ -97,6 +97,8 @@ import StoreTagEvents from "./events/StoreTagEvents.js";
97
97
  import StoreItemFolderTagEvents from "./events/StoreItemFolderTagEvents.js";
98
98
  import HostedZone, { HostedZoneRecord, HostedZoneUser } from "./entities/HostedZone.js";
99
99
  import HostedZoneEvents, { HostedZoneRecordEvents, HostedZoneUserEvents } from "./events/HostedZoneEvents.js";
100
+ import EmailAddressName from "./entities/EmailAddressName.js";
101
+ import EmailAddressNameEvents from "./events/EmailAddressNameEvents.js";
100
102
 
101
103
  @RegisterSingleton
102
104
  export default class SocialMailContextEvents extends ContextEvents {
@@ -127,6 +129,7 @@ export default class SocialMailContextEvents extends ContextEvents {
127
129
  this.register(HostedZoneUser, HostedZoneUserEvents);
128
130
  this.register(Email, EmailEvents);
129
131
  this.register(EmailAddress, EmailAddressEvents);
132
+ this.register(EmailAddressName, EmailAddressNameEvents);
130
133
  this.register(EmailEngagement, EmailEngagementEvents);
131
134
  this.register(EmailRecipient, EmailRecipientEvents);
132
135
  this.register(EmailTag, EmailTagEvents);
@@ -9,6 +9,7 @@ import Domain from "./Domain.js";
9
9
  import type MailboxContact from "./MailboxContact.js";
10
10
  import type { ContactEmail } from "./Contact.js";
11
11
  import type SubscriberActivity from "./SubscriberActivity.js";
12
+ import type EmailAddressName from "./EmailAddressName.js";
12
13
 
13
14
  @Table("EmailAddresses")
14
15
  @Index({
@@ -50,5 +51,6 @@ export default class EmailAddress {
50
51
  public contactEmails: ContactEmail[];
51
52
 
52
53
  public subscriberActivities: SubscriberActivity[];
54
+ names: EmailAddressName[];
53
55
 
54
56
  }
@@ -0,0 +1,37 @@
1
+ import Column from "@entity-access/entity-access/dist/decorators/Column.js";
2
+ import Table from "@entity-access/entity-access/dist/decorators/Table.js";
3
+ import { RelateTo } from "@entity-access/entity-access/dist/decorators/Relate.js";
4
+ import EmailAddress from "./EmailAddress.js";
5
+ import Tag from "./Tag.js";
6
+
7
+ /**
8
+ * This table exists as an index of all historical name tokens used in the email address.
9
+ *
10
+ * Akash @ Social Mail <akash@socialmail.me>
11
+ * Akash Kava <akash@socialmail.me>
12
+ * EmailAddressNameToken will contain ids of akash, kava, social, mail tokens
13
+ *
14
+ * Why not use FTS?
15
+ * FTS will not keep history, this table will keep history of names.
16
+ */
17
+
18
+ @Table("EmailAddressNames")
19
+ export default class EmailAddressName {
20
+
21
+ @Column({ dataType: "BigInt", key: true })
22
+ @RelateTo(Tag, {
23
+ property: (x) => x.tag,
24
+ inverseProperty: (x) => x.emailAddressNames
25
+ })
26
+ tagID: number;
27
+
28
+ @Column({ dataType: "BigInt", key: true })
29
+ @RelateTo(EmailAddress, {
30
+ property: (x) => x.emailAddress,
31
+ inverseProperty: (x) => x.names
32
+ })
33
+ emailAddressID: number;
34
+
35
+ tag: Tag;
36
+ emailAddress: EmailAddress;
37
+ }
@@ -5,11 +5,12 @@ import type AppFileTag from "./AppFileTag.js";
5
5
  import { RelateTo } from "@entity-access/entity-access/dist/decorators/Relate.js";
6
6
  import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
7
7
  import type { ContactTag } from "./Contact.js";
8
- import { IgnoreJsonProperty, ReadOnlyJsonProperty } from "@entity-access/server-pages/dist/services/ModelService.js";
8
+ import { ReadOnlyJsonProperty } from "@entity-access/server-pages/dist/services/ModelService.js";
9
9
  import type MailboxContactTag from "./MailboxContactTag.js";
10
10
  import type EmailTag from "./EmailTag.js";
11
11
  import type { StoreItemFolderTag, StoreItemTag, StoreTag } from "./Store.js";
12
12
  import type MailboxFolder from "./MailboxFolder.js";
13
+ import type EmailAddressName from "./EmailAddressName.js";
13
14
 
14
15
  /**
15
16
  * The reason tags table exists in form of string,bigint pair is, we need
@@ -83,4 +84,5 @@ export default class Tag {
83
84
  storeTags: StoreTag[];
84
85
  storeItemFolderTags: StoreItemFolderTag[];
85
86
  mailboxFolders: MailboxFolder[];
87
+ emailAddressNames: EmailAddressName[];
86
88
  }
@@ -0,0 +1,14 @@
1
+ import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWithParameter.js";
2
+ import EmailAddressName from "../entities/EmailAddressName.js";
3
+ import AuthenticatedEvents from "./AuthenticatedEvents.js";
4
+
5
+ export default class EmailAddressNameEvents extends AuthenticatedEvents<EmailAddressName> {
6
+
7
+ filter(query: IEntityQuery<EmailAddressName>): IEntityQuery<EmailAddressName> {
8
+ if (this.verify) {
9
+ this.sessionUser.ensureLoggedIn();
10
+ }
11
+ return query.limit(20);
12
+ }
13
+
14
+ }
@@ -3,7 +3,7 @@ import semver from "semver";
3
3
 
4
4
  export default async function seedUI(config: DBConfig) {
5
5
 
6
- const version = "1.2.502";
6
+ const version = "1.2.506";
7
7
 
8
8
  const existing = await config.getValue(UIPackageConfig, false);
9
9
  if (existing) {
@@ -1,10 +1,12 @@
1
1
  /* eslint-disable no-console */
2
- import { RegisterSingleton } from "@entity-access/entity-access/dist/di/di.js";
2
+ import { RegisterSingleton, ServiceProvider } from "@entity-access/entity-access/dist/di/di.js";
3
3
  import SocialMailContext from "../model/SocialMailContext.js";
4
4
  import { globalServices } from "../../globalServices.js";
5
5
  import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
6
6
  import { cacheFor } from "../../common/cacheFor.js";
7
7
  import Domain from "../model/entities/Domain.js";
8
+ import WorkflowContext from "@entity-access/entity-access/dist/workflows/WorkflowContext.js";
9
+ import UpdateEmailAddressNameWorkflow from "../workflows/email-address/UpdateEmailAddressNameWorkflow.js";
8
10
 
9
11
 
10
12
  @RegisterSingleton
@@ -145,6 +147,8 @@ export default class EmailAddressService {
145
147
 
146
148
  emailAddress = emailAddress.trim().toLocaleLowerCase();
147
149
 
150
+ name = name?.trim();
151
+
148
152
  const tokens = emailAddress.split("@");
149
153
  if (tokens.length !== 2) {
150
154
  if (validate) {
@@ -182,9 +186,17 @@ export default class EmailAddressService {
182
186
  // });
183
187
  const ea = await db.emailAddresses.statements.selectOrInsert(changes, { emailAddress });
184
188
  const hasMailbox = await db.mailboxes.where(ea, (p) => (x) => x.mailboxID === p.emailAddressID).some();
189
+ if (name && ea.name !== name) {
190
+ // schedule for names tag
191
+ const wc = ServiceProvider.resolve(this, WorkflowContext);
192
+ await wc.queue(UpdateEmailAddressNameWorkflow, { id: ea.emailAddressID, name });
193
+ }
185
194
  if(!hasMailbox && ((name && ea.name !== name) || ea.domainID !== domainID)) {
186
195
  ea.name = name;
187
196
  ea.domainID = domainID;
197
+
198
+ // schedule tag updates...
199
+
188
200
  await db.emailAddresses.statements.update(ea);
189
201
  // await db.emailAddresses.saveDirect({
190
202
  // mode: "update",
@@ -0,0 +1,30 @@
1
+ import Inject from "@entity-access/entity-access/dist/di/di.js";
2
+ import Workflow, { UniqueActivity } from "@entity-access/entity-access/dist/workflows/Workflow.js";
3
+ import SocialMailContext from "../../model/SocialMailContext.js";
4
+ import TagService from "../../services/tags/TagService.js";
5
+
6
+ export default class UpdateEmailAddressNameWorkflow extends Workflow<{ id: number, name: string }> {
7
+
8
+ async run() {
9
+ await this.update();
10
+ return 1;
11
+ }
12
+
13
+ @UniqueActivity
14
+ async update(
15
+ @Inject db?: SocialMailContext,
16
+ @Inject ts?: TagService
17
+ ) {
18
+ const { id: emailAddressID } = this.input;
19
+ // split tags...
20
+ const tokens = this.input.name.split(/[^\p{L}]+/igmu);
21
+ for (const token of tokens) {
22
+ if (!token) {
23
+ continue;
24
+ }
25
+ const tagID = await ts.getSystemTagID(token);
26
+ await db.emailAddressNames.statements.selectOrInsert({ tagID, emailAddressID },{ tagID, emailAddressID });
27
+ }
28
+ }
29
+
30
+ }
@@ -0,0 +1,57 @@
1
+ import Workflow, { UniqueActivity } from "@entity-access/entity-access/dist/workflows/Workflow.js";
2
+ import SocialMailContext from "../../../model/SocialMailContext.js";
3
+ import Inject from "@entity-access/entity-access/dist/di/di.js";
4
+ import Hashtags from "../../../../common/Hashtags.js";
5
+ import TagService from "../../../services/tags/TagService.js";
6
+ import { Email } from "../../../model/entities/Email.js";
7
+
8
+ export default class RepairEmailNameTagsWorkflow extends Workflow {
9
+
10
+ static taskGroup = "batch";
11
+
12
+ async run() {
13
+ let start = 0;
14
+ do{
15
+ start = await this.fixEmailTags(start);
16
+ } while(BigInt(start));
17
+ }
18
+
19
+ @UniqueActivity
20
+ async fixEmailTags(
21
+ start: number,
22
+ @Inject db?: SocialMailContext,
23
+ @Inject ts?: TagService
24
+ ) {
25
+
26
+ for(let i = 0;i< 100;i++) {
27
+ const emails = await db.emailAddresses.where({ start }, (p) => (x) => x.emailAddressID > p.start)
28
+ .orderBy(void 0, (p) => (x) => x.emailAddressID)
29
+ .limit(10)
30
+ .toArray();
31
+
32
+ if (!emails.length) {
33
+ return 0;
34
+ }
35
+
36
+ for (const { emailAddressID, name } of emails) {
37
+ start = emailAddressID;
38
+ if (!name) {
39
+ continue;
40
+ }
41
+ // fix tag...
42
+ const tokens = name.split(/[^\p{L}]+/igmu);
43
+ for (const token of tokens) {
44
+ if (!token) {
45
+ continue;
46
+ }
47
+ const tagID = await ts.getSystemTagID(token);
48
+ await db.emailAddressNames.statements.selectOrInsert({ tagID, emailAddressID },{ tagID, emailAddressID });
49
+ }
50
+ }
51
+ db.changeSet.clear();
52
+ }
53
+ return start;
54
+ }
55
+
56
+
57
+ }