@social-mail/social-mail-web-server 1.15.2 → 1.16.2

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 (80) hide show
  1. package/content/json/isd.json +780 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/server/model/entities/GeoEntity.d.ts +2 -0
  4. package/dist/server/model/entities/GeoEntity.d.ts.map +1 -1
  5. package/dist/server/model/entities/GeoEntity.js +8 -0
  6. package/dist/server/model/entities/GeoEntity.js.map +1 -1
  7. package/dist/server/model/entities/HostedZone.d.ts +0 -2
  8. package/dist/server/model/entities/HostedZone.d.ts.map +1 -1
  9. package/dist/server/model/entities/HostedZone.js.map +1 -1
  10. package/dist/server/model/entities/WebSiteHost.d.ts +0 -8
  11. package/dist/server/model/entities/WebSiteHost.d.ts.map +1 -1
  12. package/dist/server/model/entities/WebSiteHost.js +0 -14
  13. package/dist/server/model/entities/WebSiteHost.js.map +1 -1
  14. package/dist/server/model/events/AccessTokenEvents.d.ts +2 -0
  15. package/dist/server/model/events/AccessTokenEvents.d.ts.map +1 -1
  16. package/dist/server/model/events/AccessTokenEvents.js +9 -0
  17. package/dist/server/model/events/AccessTokenEvents.js.map +1 -1
  18. package/dist/server/model/events/AuthenticatedEvents.d.ts.map +1 -1
  19. package/dist/server/model/events/AuthenticatedEvents.js +13 -3
  20. package/dist/server/model/events/AuthenticatedEvents.js.map +1 -1
  21. package/dist/server/model/events/HostedDomainEvents.d.ts +1 -0
  22. package/dist/server/model/events/HostedDomainEvents.d.ts.map +1 -1
  23. package/dist/server/model/events/HostedDomainEvents.js +6 -0
  24. package/dist/server/model/events/HostedDomainEvents.js.map +1 -1
  25. package/dist/server/model/events/MailboxContactTagEvents.d.ts +2 -0
  26. package/dist/server/model/events/MailboxContactTagEvents.d.ts.map +1 -1
  27. package/dist/server/model/events/MailboxContactTagEvents.js +6 -0
  28. package/dist/server/model/events/MailboxContactTagEvents.js.map +1 -1
  29. package/dist/server/model/events/MailboxTagEvents.d.ts +3 -1
  30. package/dist/server/model/events/MailboxTagEvents.d.ts.map +1 -1
  31. package/dist/server/model/events/MailboxTagEvents.js +10 -0
  32. package/dist/server/model/events/MailboxTagEvents.js.map +1 -1
  33. package/dist/server/model/events/SubscriptionDomainEvents.d.ts +2 -0
  34. package/dist/server/model/events/SubscriptionDomainEvents.d.ts.map +1 -1
  35. package/dist/server/model/events/SubscriptionDomainEvents.js +10 -0
  36. package/dist/server/model/events/SubscriptionDomainEvents.js.map +1 -1
  37. package/dist/server/model/events/SubscriptionWebSiteEvents.d.ts +2 -0
  38. package/dist/server/model/events/SubscriptionWebSiteEvents.d.ts.map +1 -1
  39. package/dist/server/model/events/SubscriptionWebSiteEvents.js +10 -0
  40. package/dist/server/model/events/SubscriptionWebSiteEvents.js.map +1 -1
  41. package/dist/server/model/events/VerificationTokenAddressEvents.d.ts +2 -0
  42. package/dist/server/model/events/VerificationTokenAddressEvents.d.ts.map +1 -1
  43. package/dist/server/model/events/VerificationTokenAddressEvents.js +9 -0
  44. package/dist/server/model/events/VerificationTokenAddressEvents.js.map +1 -1
  45. package/dist/server/model/events/VerificationTokenEvents.d.ts +1 -0
  46. package/dist/server/model/events/VerificationTokenEvents.d.ts.map +1 -1
  47. package/dist/server/model/events/VerificationTokenEvents.js +9 -0
  48. package/dist/server/model/events/VerificationTokenEvents.js.map +1 -1
  49. package/dist/server/model/events/WebSiteHostEvents.d.ts +0 -3
  50. package/dist/server/model/events/WebSiteHostEvents.d.ts.map +1 -1
  51. package/dist/server/model/events/WebSiteHostEvents.js +1 -26
  52. package/dist/server/model/events/WebSiteHostEvents.js.map +1 -1
  53. package/dist/server/seed/ui/seed-ui.js +2 -2
  54. package/dist/server/seed/ui/seed-ui.js.map +1 -1
  55. package/dist/server/services/DBConfig.js +3 -3
  56. package/dist/server/services/DBConfig.js.map +1 -1
  57. package/dist/server/workflows/dns/SyncDnsZoneRecordsWorkflow.d.ts.map +1 -1
  58. package/dist/server/workflows/dns/SyncDnsZoneRecordsWorkflow.js +32 -36
  59. package/dist/server/workflows/dns/SyncDnsZoneRecordsWorkflow.js.map +1 -1
  60. package/dist/server/workflows/geo-entities/DownloadGeoEntitiesWorkflow.d.ts.map +1 -1
  61. package/dist/server/workflows/geo-entities/DownloadGeoEntitiesWorkflow.js +20 -7
  62. package/dist/server/workflows/geo-entities/DownloadGeoEntitiesWorkflow.js.map +1 -1
  63. package/package.json +2 -2
  64. package/src/server/model/entities/GeoEntity.ts +6 -0
  65. package/src/server/model/entities/HostedZone.ts +0 -2
  66. package/src/server/model/entities/WebSiteHost.ts +0 -15
  67. package/src/server/model/events/AccessTokenEvents.ts +11 -0
  68. package/src/server/model/events/AuthenticatedEvents.ts +13 -3
  69. package/src/server/model/events/HostedDomainEvents.ts +7 -0
  70. package/src/server/model/events/MailboxContactTagEvents.ts +7 -0
  71. package/src/server/model/events/MailboxTagEvents.ts +13 -0
  72. package/src/server/model/events/SubscriptionDomainEvents.ts +12 -1
  73. package/src/server/model/events/SubscriptionWebSiteEvents.ts +12 -0
  74. package/src/server/model/events/VerificationTokenAddressEvents.ts +11 -0
  75. package/src/server/model/events/VerificationTokenEvents.ts +10 -0
  76. package/src/server/model/events/WebSiteHostEvents.ts +1 -18
  77. package/src/server/seed/ui/seed-ui.ts +2 -2
  78. package/src/server/services/DBConfig.ts +2 -2
  79. package/src/server/workflows/dns/SyncDnsZoneRecordsWorkflow.ts +63 -70
  80. package/src/server/workflows/geo-entities/DownloadGeoEntitiesWorkflow.ts +23 -7
@@ -8,7 +8,6 @@ import { JsonProperty, ReadOnlyJsonProperty } from "@entity-access/server-pages/
8
8
  import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
9
9
  import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
10
10
  import { User } from "./User.js";
11
- import type { WebSiteHost } from "./WebSiteHost.js";
12
11
 
13
12
  const { labels, column: TypeColumn} = EnumColumn(["A", "AAAA", "CNAME", "MX", "TXT", "PTR", "SRV", "CAA", "NS", "SOA" ] as const, 15, { default: () => "A"});
14
13
 
@@ -55,7 +54,6 @@ export default class HostedZone {
55
54
 
56
55
  @JsonProperty({})
57
56
  zone: string;
58
- webSiteHosts: WebSiteHost[];
59
57
 
60
58
  }
61
59
 
@@ -2,14 +2,8 @@ import Column from "@entity-access/entity-access/dist/decorators/Column.js";
2
2
  import { RelateTo } from "@entity-access/entity-access/dist/decorators/Relate.js";
3
3
  import Table from "@entity-access/entity-access/dist/decorators/Table.js";
4
4
  import WebSite from "./WebSite.js";
5
- import HostedZone from "./HostedZone.js";
6
5
 
7
6
 
8
- /**
9
- * The reason web site host has ZoneID is, we don't want to popuplate websites
10
- * with assuming that the zone has wildcard, that can cause confusion and investigation
11
- * can cause lot of issues. Wildcards also increase unncessary attack surface.
12
- */
13
7
  @Table("WebSiteHosts")
14
8
  export class WebSiteHost {
15
9
 
@@ -26,15 +20,6 @@ export class WebSiteHost {
26
20
  })
27
21
  public folderID: number;
28
22
 
29
- @Column({ dataType: "BigInt", nullable: true})
30
- @RelateTo(HostedZone, {
31
- property: (x) => x.zone,
32
- inverseProperty: (x) => x.webSiteHosts
33
- })
34
- public zoneID: number;
35
-
36
23
  public folder: WebSite;
37
24
 
38
- public zone: HostedZone;
39
-
40
25
  }
@@ -3,9 +3,20 @@ import AccessToken from "../entities/AccessToken.js";
3
3
  import AuthenticatedEvents from "./AuthenticatedEvents.js";
4
4
  import { randomUUID } from "crypto";
5
5
  import { AppStringHelper } from "../../../common/AppStringHelper.js";
6
+ import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWithParameter.js";
6
7
 
7
8
  export default class AccessTokenEvents extends AuthenticatedEvents<AccessToken> {
8
9
 
10
+ filter(query: IEntityQuery<AccessToken>): IEntityQuery<AccessToken> {
11
+ if (this.verify) {
12
+ this.sessionUser.ensureLoggedIn();
13
+ }
14
+ if(this.sessionUser.isAdmin) {
15
+ return query;
16
+ }
17
+ return query.where(this.sessionUser, (x, p) => x.userID === p.userID);
18
+ }
19
+
9
20
  beforeInsert(entity: AccessToken, entry: ChangeEntry<AccessToken>) {
10
21
 
11
22
  if (this.verify) {
@@ -12,24 +12,34 @@ const done = Promise.resolve();
12
12
  */
13
13
  export default class AuthenticatedEvents<T> extends BaseEvents<T> {
14
14
  filter(query: IEntityQuery<T>): IEntityQuery<T> {
15
+ if (this.sessionUser.isAdmin) {
16
+ return query;
17
+ }
15
18
  if (this.verify) {
16
19
  this.sessionUser.ensureLoggedIn(() => new EntityAccessError(`Login Required to get ${this.entityName}`));
17
20
  }
18
- return query;
21
+ // implementor should create the correct filter..
22
+ return query.where((x) => false);
19
23
  }
20
24
 
21
25
  modify(query: IEntityQuery<T>): IEntityQuery<T> {
26
+ if (this.sessionUser.isAdmin) {
27
+ return query;
28
+ }
22
29
  if (this.verify) {
23
30
  this.sessionUser.ensureIsAdmin(() => new EntityAccessError(`Admin access required to modify ${this.entityName}`));
24
31
  }
25
- return query;
32
+ return query.where((x) => false);
26
33
  }
27
34
 
28
35
  delete(query: IEntityQuery<T>): IEntityQuery<T> {
36
+ if (this.sessionUser.isAdmin) {
37
+ return query;
38
+ }
29
39
  if (this.verify) {
30
40
  this.sessionUser.ensureIsAdmin(() => new EntityAccessError(`Admin access required to delete ${this.entityName}`));
31
41
  }
32
- return query;
42
+ return query.where((x) => false);
33
43
  }
34
44
 
35
45
  beforeInsert(entity: T, entry: ChangeEntry<T>): void | Promise<void> {
@@ -50,6 +50,13 @@ export default class HostedDomainEvents extends AuthenticatedEvents<HostedDomain
50
50
  return { domainID };
51
51
  }
52
52
 
53
+ filter(query: IEntityQuery<HostedDomain>): IEntityQuery<HostedDomain> {
54
+ if (this.verify) {
55
+ this.sessionUser.ensureLoggedIn();
56
+ }
57
+ return query;
58
+ }
59
+
53
60
  modify(query: IEntityQuery<HostedDomain>): IEntityQuery<HostedDomain> {
54
61
  if (this.verify) {
55
62
  this.sessionUser.ensureLoggedIn();
@@ -1,6 +1,13 @@
1
+ import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWithParameter.js";
1
2
  import MailboxContactTag from "../entities/MailboxContactTag.js";
2
3
  import AuthenticatedEvents from "./AuthenticatedEvents.js";
3
4
 
4
5
  export default class MailboxContactTagEvents extends AuthenticatedEvents<MailboxContactTag> {
5
6
 
7
+ filter(query: IEntityQuery<MailboxContactTag>): IEntityQuery<MailboxContactTag> {
8
+ if (this.verify) {
9
+ this.sessionUser.ensureLoggedIn();
10
+ }
11
+ return query;
12
+ }
6
13
  }
@@ -6,6 +6,7 @@ import MailboxTag from "../entities/MailboxTag.js";
6
6
  import AuthenticatedEvents from "./AuthenticatedEvents.js";
7
7
  import Page from "@entity-access/server-pages/dist/Page.js";
8
8
  import SocialMailContext from "../SocialMailContext.js";
9
+ import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWithParameter.js";
9
10
 
10
11
  export default class MailboxTagEvents extends AuthenticatedEvents<MailboxTag> {
11
12
 
@@ -28,4 +29,16 @@ export default class MailboxTagEvents extends AuthenticatedEvents<MailboxTag> {
28
29
  return q.limit(50);
29
30
  }
30
31
 
32
+ filter(query: IEntityQuery<MailboxTag>): IEntityQuery<MailboxTag> {
33
+ if (this.verify) {
34
+ this.sessionUser.ensureLoggedIn();
35
+ }
36
+ if (this.sessionUser.isAdmin) {
37
+ return query;
38
+ }
39
+ return query.where(this.sessionUser, (x, p) =>
40
+ x.mailbox.userMailboxes.some((um) => um.userID === p.userID)
41
+ || x.mailbox.domain.hostedDomain.domainUsers.some((d) => d.userID === p.userID));
42
+ }
43
+
31
44
  }
@@ -1,6 +1,17 @@
1
+ import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWithParameter.js";
1
2
  import SubscriptionDomain from "../entities/SubscriptionDomain.js";
2
3
  import AuthenticatedEvents from "./AuthenticatedEvents.js";
3
4
 
4
5
  export default class SubscriptionDomainEvents extends AuthenticatedEvents<SubscriptionDomain> {
5
-
6
+ filter(query: IEntityQuery<SubscriptionDomain>): IEntityQuery<SubscriptionDomain> {
7
+ if(this.verify) {
8
+ this.sessionUser.ensureLoggedIn();
9
+ }
10
+ if (this.sessionUser.isAdmin) {
11
+ return query;
12
+ }
13
+ return query.where(this.sessionUser,(x, p) => x.subscription.buyer.userID === p.userID
14
+ || x.subscription.store.folderID in p.readWebSiteAccess
15
+ );
16
+ }
6
17
  }
@@ -1,6 +1,18 @@
1
+ import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWithParameter.js";
1
2
  import SubscriptionWebSite from "../entities/SubscriptionWebSite.js";
2
3
  import AuthenticatedEvents from "./AuthenticatedEvents.js";
3
4
 
4
5
  export default class SubscriptionWebSiteEvents extends AuthenticatedEvents<SubscriptionWebSite> {
5
6
 
7
+ filter(query: IEntityQuery<SubscriptionWebSite>): IEntityQuery<SubscriptionWebSite> {
8
+ if(this.verify) {
9
+ this.sessionUser.ensureLoggedIn();
10
+ }
11
+ if (this.sessionUser.isAdmin) {
12
+ return query;
13
+ }
14
+ return query.where(this.sessionUser,(x, p) => x.subscription.buyer.userID === p.userID
15
+ || x.subscription.store.folderID in p.readWebSiteAccess
16
+ );
17
+ }
6
18
  }
@@ -2,9 +2,20 @@ import ChangeEntry from "@entity-access/entity-access/dist/model/changes/ChangeE
2
2
  import { VerificationTokenAddress } from "../entities/VerificationToken.js";
3
3
  import AuthenticatedEvents from "./AuthenticatedEvents.js";
4
4
  import { AppStringHelper } from "../../../common/AppStringHelper.js";
5
+ import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWithParameter.js";
5
6
 
6
7
  export default class VerificationTokenAddressEvent extends AuthenticatedEvents<VerificationTokenAddress> {
7
8
 
9
+ filter(query: IEntityQuery<VerificationTokenAddress>): IEntityQuery<VerificationTokenAddress> {
10
+ if(this.verify) {
11
+ this.sessionUser.ensureLoggedIn();
12
+ }
13
+ if (this.sessionUser.isAdmin) {
14
+ return query;
15
+ }
16
+ return query.where(this.sessionUser,(x, p) => x.verificationToken.userID === p.userID);
17
+ }
18
+
8
19
  beforeInsert(entity: VerificationTokenAddress, entry: ChangeEntry<VerificationTokenAddress>) {
9
20
  // do nothing
10
21
  }
@@ -289,6 +289,16 @@ export default class VerificationTokenEvents extends AuthenticatedEvents<Verific
289
289
  return this.captchaService.getVideo(entity.code);
290
290
  }
291
291
 
292
+ filter(query: IEntityQuery<VerificationToken>): IEntityQuery<VerificationToken> {
293
+ if(this.verify) {
294
+ this.sessionUser.ensureLoggedIn();
295
+ }
296
+ if (this.sessionUser.isAdmin) {
297
+ return query;
298
+ }
299
+ return query.where(this.sessionUser,(x, p) => x.userID === p.userID);
300
+ }
301
+
292
302
  async beforeInsert(entity: VerificationToken, entry: ChangeEntry<VerificationToken>) {
293
303
 
294
304
  const { type } = entity;
@@ -1,4 +1,4 @@
1
- import Inject, { ServiceProvider } from "@entity-access/entity-access/dist/di/di.js";
1
+ import { ServiceProvider } from "@entity-access/entity-access/dist/di/di.js";
2
2
  import ChangeEntry from "@entity-access/entity-access/dist/model/changes/ChangeEntry.js";
3
3
  import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWithParameter.js";
4
4
  import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
@@ -9,13 +9,9 @@ import { WebSiteHost } from "../entities/WebSiteHost.js";
9
9
  import AuthenticatedEvents from "./AuthenticatedEvents.js";
10
10
  import WebSiteVersionService from "../../services/files/WebSiteVersionService.js";
11
11
  import { AppWorkflowContext } from "../../workflows/AppWorkflowContext.js";
12
- import SocialMailContext from "../SocialMailContext.js";
13
12
 
14
13
  export class WebSiteHostEvents extends AuthenticatedEvents<WebSiteHost> {
15
14
 
16
- @Inject
17
- db: SocialMailContext;
18
-
19
15
  filter(query: IEntityQuery<WebSiteHost>) {
20
16
  if (this.sessionUser.isAdmin) {
21
17
  return query;
@@ -43,19 +39,6 @@ export class WebSiteHostEvents extends AuthenticatedEvents<WebSiteHost> {
43
39
 
44
40
  beforeInsert(entity: WebSiteHost, entry: ChangeEntry<WebSiteHost>) {
45
41
  // do nothing
46
- entity.host = entity.host.trim().toLowerCase();
47
- }
48
-
49
- async beforeDelete(entity: WebSiteHost, entry: ChangeEntry<WebSiteHost>) {
50
- const { zoneID, host } = entity;
51
- if (!zoneID) {
52
- return;
53
- }
54
- await this.db.hostedZoneRecords.withKeys({ zoneID, fqdn: host })
55
- .delete();
56
-
57
- const wc = ServiceProvider.resolve(this, AppWorkflowContext);
58
- await SyncDnsZoneRecordsWorkflow.enqueue(wc, zoneID);
59
42
  }
60
43
 
61
44
  async afterInsert(entity: WebSiteHost, entry: ChangeEntry<WebSiteHost>) {
@@ -17,13 +17,13 @@ export default async function seedUI(config: DBConfig) {
17
17
  await config.saveVersion(UIPackageConfig, {
18
18
  package: "@social-mail/social-mail-client",
19
19
  view: "dist/web/AppIndex",
20
- version: "1.10.95"
20
+ version: "1.11.7"
21
21
  });
22
22
 
23
23
  await config.saveVersion(WebComponentsPackageConfig, {
24
24
  package: "@social-mail/web-components",
25
25
  view: "dist/index.js",
26
- version: "1.0.419"
26
+ version: "1.1.9"
27
27
  });
28
28
 
29
29
  await config.saveVersion(FAFreePackageConfig, {
@@ -104,12 +104,12 @@ export default class DBConfig {
104
104
  public async save<T>(type: IClassOf<T>, values: Partial<T>, seed = false, name = type.name) {
105
105
  let config;
106
106
  if (seed) {
107
- config = await this.context.configurations.statements.selectOrInsert({ name, configValue: JSON.stringify(values, void 0, 4)} as any, { name });
108
- } else {
109
107
  config = await this.context.configurations.statements.upsert({
110
108
  name,
111
109
  configValue: JSON.stringify(values, void 0, 4)
112
110
  } as any, void 0, { name });
111
+ } else {
112
+ config = await this.context.configurations.statements.selectOrInsert({ name, configValue: JSON.stringify(values, void 0, 4)} as any, { name });
113
113
  }
114
114
  const ci = new ConfigItem(config, this, type);
115
115
  return ci;
@@ -11,9 +11,6 @@ import { AppWorkflowContext } from "../AppWorkflowContext.js";
11
11
  const toUnixDateAndHour = (date: Date | DateTime, d = DateTime.from(date)) =>
12
12
  `${StringFormat.fixed(d.year, 4)}${StringFormat.fixed(d.month)}${StringFormat.fixed(d.day)}${StringFormat.fixed(d.hour)}`;
13
13
 
14
- const ttlHour = 60*60;
15
- const ttlDay = 24*ttlHour;
16
-
17
14
  export default class SyncDnsZoneRecordsWorkflow extends Workflow {
18
15
 
19
16
  static enqueue(context: AppWorkflowContext, zoneID) {
@@ -63,6 +60,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
63
60
 
64
61
  const { name: domain } = await db.domains.statements.select({}, { domainID: zoneID });
65
62
 
63
+ const ttl = 8600;
66
64
  const dateCreated = DateTime.now;
67
65
  const dateUpdated = dateCreated;
68
66
 
@@ -89,7 +87,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
89
87
  zoneID,
90
88
  dateCreated,
91
89
  dateUpdated,
92
- ttl: ttlDay,
90
+ ttl,
93
91
  name: "@",
94
92
  type: "NS",
95
93
  value: ns,
@@ -103,7 +101,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
103
101
  zoneID,
104
102
  dateCreated,
105
103
  dateUpdated,
106
- ttl: ttlDay,
104
+ ttl,
107
105
  name: "_acme-challenge",
108
106
  type: "CNAME",
109
107
  value: `${domain}.${globalEnv.dns.letsEncryptPrefix}`,
@@ -115,7 +113,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
115
113
  zoneID,
116
114
  dateCreated,
117
115
  dateUpdated,
118
- ttl: ttlDay,
116
+ ttl,
119
117
  name: "_dmarc",
120
118
  type: "TXT",
121
119
  value: `v=DMARC1; p=reject;`,
@@ -127,7 +125,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
127
125
  zoneID,
128
126
  dateCreated,
129
127
  dateUpdated,
130
- ttl: ttlDay,
128
+ ttl,
131
129
  type: "TXT",
132
130
  name: "@",
133
131
  value: `v=spf1 include:_spf.socialmail.in ~all`,
@@ -138,7 +136,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
138
136
  zoneID,
139
137
  dateCreated,
140
138
  dateUpdated,
141
- ttl: ttlHour,
139
+ ttl,
142
140
  type: "A",
143
141
  name: "@",
144
142
  value: "$IP$",
@@ -151,7 +149,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
151
149
  zoneID,
152
150
  dateCreated,
153
151
  dateUpdated,
154
- ttl: ttlDay,
152
+ ttl,
155
153
  type: "CNAME",
156
154
  name: "www",
157
155
  value: "$HOST$",
@@ -163,7 +161,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
163
161
  zoneID,
164
162
  dateCreated,
165
163
  dateUpdated,
166
- ttl: ttlDay,
164
+ ttl,
167
165
  type: "CNAME",
168
166
  name: "mails",
169
167
  value: "$HOST$",
@@ -175,7 +173,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
175
173
  zoneID,
176
174
  dateCreated,
177
175
  dateUpdated,
178
- ttl: ttlDay,
176
+ ttl,
179
177
  type: "CNAME",
180
178
  name: "www",
181
179
  value: "$HOST$",
@@ -183,6 +181,19 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
183
181
  readonly: true
184
182
  });
185
183
 
184
+ // await db.hostedZoneRecords.statements.insert({
185
+ // zoneID,
186
+ // dateCreated,
187
+ // dateUpdated,
188
+ // ttl,
189
+ // type: "CNAME",
190
+ // name: "*",
191
+ // value: "$HOST$",
192
+ // fqdn: `*.${domain}`,
193
+ // hosted: true,
194
+ // readonly: true
195
+ // });
196
+
186
197
  }
187
198
 
188
199
  @UniqueActivity
@@ -209,26 +220,21 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
209
220
 
210
221
  const dateCreated = DateTime.now;
211
222
  const dateUpdated = dateCreated;
212
- const ttl = ttlDay;
223
+ const ttl = 8600;
213
224
 
214
225
  // sync...
215
- await db.hostedZoneRecords
216
- .withKeys({
217
- zoneID,
218
- name,
219
- type
220
- }).updateOrInsert({
221
- zoneID,
222
- name,
223
- type,
224
- value,
225
- fqdn,
226
- readonly: true,
227
- dateCreated,
228
- dateUpdated,
229
- hosted: true,
230
- ttl
231
- });
226
+ await db.hostedZoneRecords.statements.upsert({
227
+ zoneID,
228
+ name,
229
+ type,
230
+ value,
231
+ fqdn,
232
+ readonly: true,
233
+ dateCreated,
234
+ dateUpdated,
235
+ hosted: true,
236
+ ttl
237
+ }, void 0, { zoneID, name, type });
232
238
  }
233
239
 
234
240
  @UniqueActivity
@@ -242,7 +248,7 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
242
248
 
243
249
  const dateCreated = DateTime.now;
244
250
  const dateUpdated = dateCreated;
245
- const ttl = ttlDay;
251
+ const ttl = 8600;
246
252
 
247
253
  /** Sync all domain keys */
248
254
 
@@ -257,20 +263,18 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
257
263
  const fqdn = `${name}.${domain.name}`;
258
264
 
259
265
  // sync...
260
- await db.hostedZoneRecords
261
- .withKeys({ zoneID, name, type })
262
- .updateOrInsert({
263
- zoneID,
264
- name,
265
- type,
266
- value,
267
- fqdn,
268
- readonly: true,
269
- dateCreated,
270
- dateUpdated,
271
- hosted: true,
272
- ttl,
273
- });
266
+ await db.hostedZoneRecords.statements.upsert({
267
+ zoneID,
268
+ name,
269
+ type,
270
+ value,
271
+ fqdn,
272
+ readonly: true,
273
+ dateCreated,
274
+ dateUpdated,
275
+ hosted: true,
276
+ ttl,
277
+ }, void 0, { zoneID, name, type });
274
278
  }
275
279
  }
276
280
 
@@ -301,13 +305,10 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
301
305
 
302
306
  const dateCreated = DateTime.now;
303
307
  const dateUpdated = dateCreated;
304
- const ttl = ttlDay;
308
+ const ttl = 8600;
305
309
 
306
310
  const hosts = await db.websiteFolderHosts
307
- .where({ domainName, hostMatch }, (x, p) =>
308
- (x.host === p.domainName || Sql.text.iLike(x.host, p.hostMatch))
309
- && x.zoneID === null
310
- )
311
+ .where({ domainName, hostMatch }, (x, p) => x.host === p.domainName || Sql.text.iLike(x.host, p.hostMatch) )
311
312
  .toArray();
312
313
 
313
314
  for (const host of hosts) {
@@ -323,27 +324,19 @@ export default class SyncDnsZoneRecordsWorkflow extends Workflow {
323
324
  const value = `$HOST$`;
324
325
  const fqdn = `${name}.${domainName}`;
325
326
 
326
- await db.hostedZoneRecords
327
- .withKeys({
328
- zoneID,
329
- name,
330
- type
331
- }).updateOrInsert({
332
- zoneID,
333
- name,
334
- type,
335
- value,
336
- fqdn,
337
- readonly: true,
338
- dateCreated,
339
- dateUpdated,
340
- ttl,
341
- hosted: true,
342
- });
343
-
344
- await db.websiteFolderHosts
345
- .withKeys({ host: host.host })
346
- .update({ zoneID });
327
+ // sync...
328
+ await db.hostedZoneRecords.statements.upsert({
329
+ zoneID,
330
+ name,
331
+ type,
332
+ value,
333
+ fqdn,
334
+ readonly: true,
335
+ dateCreated,
336
+ dateUpdated,
337
+ ttl,
338
+ hosted: true,
339
+ }, void 0, { zoneID, name, type });
347
340
  }
348
341
  }
349
342
 
@@ -12,6 +12,8 @@ import { globalEnv } from "../../../common/globalEnv.js";
12
12
  import QueryBuilder from "../../../common/QueryBuilder.js";
13
13
  import SecureFetchBuilder from "../../../common/fetch/SecureFetchBuilder.js";
14
14
  import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
15
+ import { fileURLToPath } from "node:url";
16
+ import { readFile } from "node:fs/promises";
15
17
 
16
18
  /**
17
19
  * For same phyical server, we should only download it once
@@ -30,7 +32,12 @@ export default class DownloadGeoEntitiesWorkflow extends Workflow {
30
32
 
31
33
  async run() {
32
34
 
33
- if (!globalEnv.isRootHost || globalEnv.otpIn.host) {
35
+ if (globalEnv.isRootHost) {
36
+ await this.downloadFromGeoNames();
37
+ return;
38
+ }
39
+
40
+ if (globalEnv.otpIn.host) {
34
41
  // download from parent...
35
42
  await this.downloadFromHost("country");
36
43
  await this.downloadFromHost("state");
@@ -113,9 +120,13 @@ export default class DownloadGeoEntitiesWorkflow extends Workflow {
113
120
  let countryField;
114
121
  let currencyCodeField;
115
122
  let currencyNameField;
123
+ let phoneField;
116
124
 
117
125
  let total = 0;
118
126
 
127
+ const isdJson = JSON.parse(await readFile(fileURLToPath(import.meta.resolve("../../../../content/json/isd.json")), "utf-8"));
128
+ const isdCountries = isdJson.countries as { iso_code, mask, dial_code }[];
129
+
119
130
  for await(const line of file.lines()) {
120
131
  if(line.startsWith("#")) {
121
132
  last = line;
@@ -137,6 +148,9 @@ export default class DownloadGeoEntitiesWorkflow extends Workflow {
137
148
  case "fips":
138
149
  fipsField = fieldID;
139
150
  break;
151
+ case "Phone":
152
+ phoneField = fieldID;
153
+ break;
140
154
  case "Country":
141
155
  countryField = fieldID;
142
156
  break;
@@ -164,12 +178,18 @@ export default class DownloadGeoEntitiesWorkflow extends Workflow {
164
178
  const currencyCode = tokens[currencyCodeField];
165
179
  const currencyName = tokens[currencyNameField];
166
180
 
181
+ const isdItem = isdCountries.find((x) => x.iso_code === code);
182
+ const phoneFormat = isdItem?.mask;
183
+ const isdCode = isdItem?.dial_code ?? tokens[phoneField];
184
+
167
185
  const fields = {
168
186
  fips,
169
187
  name,
170
188
  code,
171
189
  currencyCode,
172
190
  currencyName,
191
+ isdCode,
192
+ phoneFormat
173
193
  };
174
194
 
175
195
  await this.save(db, "country", externalID, fields);
@@ -187,11 +207,7 @@ export default class DownloadGeoEntitiesWorkflow extends Workflow {
187
207
  fields.fullName = fields.name;
188
208
  fields.name = fields.name.toLowerCase();
189
209
  fields.dateUpdated = this.currentTime;
190
- const n = await db.geoEntities.statements.update(fields, keys);
191
- if (n) {
192
- return;
193
- }
194
- await db.geoEntities.statements.selectOrInsert(fields, keys);
210
+ await db.geoEntities.withKeys(keys).updateOrInsert(fields);
195
211
  }
196
212
 
197
213
  async downloadStates(tfs: TempFileService, db: SocialMailContext) {
@@ -330,7 +346,7 @@ export default class DownloadGeoEntitiesWorkflow extends Workflow {
330
346
  async exists(db: SocialMailContext) {
331
347
  // download only once a month
332
348
  const past = DateTime.now.addDays(-30);
333
- const exists = await db.geoEntities.where({ past }, (x, p) => x.dateCreated > p.past)
349
+ const exists = await db.geoEntities.where({ past }, (x, p) => x.dateUpdated > p.past)
334
350
  .some();
335
351
  return exists;
336
352
  }