@social-mail/social-mail-web-server 1.7.232 → 1.7.233

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 (46) hide show
  1. package/dist/WebServer.d.ts.map +1 -1
  2. package/dist/WebServer.js +0 -2
  3. package/dist/WebServer.js.map +1 -1
  4. package/dist/common/GlobalEvents.d.ts +1 -47
  5. package/dist/common/GlobalEvents.d.ts.map +1 -1
  6. package/dist/common/GlobalEvents.js +231 -243
  7. package/dist/common/GlobalEvents.js.map +1 -1
  8. package/dist/common/globalEnv.d.ts +9 -0
  9. package/dist/common/globalEnv.d.ts.map +1 -1
  10. package/dist/common/globalEnv.js +9 -0
  11. package/dist/common/globalEnv.js.map +1 -1
  12. package/dist/server/model/events/DomainKeyEvents.d.ts +0 -1
  13. package/dist/server/model/events/DomainKeyEvents.d.ts.map +1 -1
  14. package/dist/server/model/events/DomainKeyEvents.js +0 -5
  15. package/dist/server/model/events/DomainKeyEvents.js.map +1 -1
  16. package/dist/server/model/events/WebSiteHostEvents.d.ts +0 -1
  17. package/dist/server/model/events/WebSiteHostEvents.d.ts.map +1 -1
  18. package/dist/server/model/events/WebSiteHostEvents.js +1 -15
  19. package/dist/server/model/events/WebSiteHostEvents.js.map +1 -1
  20. package/dist/server/services/message-events/MessagingService.d.ts +17 -0
  21. package/dist/server/services/message-events/MessagingService.d.ts.map +1 -0
  22. package/dist/server/services/message-events/MessagingService.js +42 -0
  23. package/dist/server/services/message-events/MessagingService.js.map +1 -0
  24. package/dist/server/services/message-events/PgEvents.d.ts +13 -0
  25. package/dist/server/services/message-events/PgEvents.d.ts.map +1 -0
  26. package/dist/server/services/message-events/PgEvents.js +215 -0
  27. package/dist/server/services/message-events/PgEvents.js.map +1 -0
  28. package/dist/server/smtp/services/WebSiteChannelService.d.ts +0 -2
  29. package/dist/server/smtp/services/WebSiteChannelService.d.ts.map +1 -1
  30. package/dist/server/smtp/services/WebSiteChannelService.js +6 -20
  31. package/dist/server/smtp/services/WebSiteChannelService.js.map +1 -1
  32. package/dist/server/workflows/dns/SyncDnsZoneRecordsWorkflow.d.ts +2 -2
  33. package/dist/server/workflows/dns/SyncDnsZoneRecordsWorkflow.d.ts.map +1 -1
  34. package/dist/server/workflows/dns/SyncDnsZoneRecordsWorkflow.js +4 -4
  35. package/dist/server/workflows/dns/SyncDnsZoneRecordsWorkflow.js.map +1 -1
  36. package/dist/tsconfig.tsbuildinfo +1 -1
  37. package/package.json +3 -3
  38. package/src/WebServer.ts +0 -3
  39. package/src/common/GlobalEvents.ts +249 -249
  40. package/src/common/globalEnv.ts +11 -0
  41. package/src/server/model/events/DomainKeyEvents.ts +0 -5
  42. package/src/server/model/events/WebSiteHostEvents.ts +0 -4
  43. package/src/server/services/message-events/MessagingService.ts +43 -0
  44. package/src/server/services/message-events/PgEvents.ts +153 -0
  45. package/src/server/smtp/services/WebSiteChannelService.ts +5 -22
  46. package/src/server/workflows/dns/SyncDnsZoneRecordsWorkflow.ts +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-web-server",
3
- "version": "1.7.232",
3
+ "version": "1.7.233",
4
4
  "description": "## Phase 1",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -21,8 +21,8 @@
21
21
  "dependencies": {
22
22
  "@aws-sdk/client-s3": "^3.717.0",
23
23
  "@azure/storage-blob": "^12.25.0",
24
- "@entity-access/entity-access": "^1.0.402",
25
- "@entity-access/server-pages": "^1.1.403",
24
+ "@entity-access/entity-access": "^1.0.403",
25
+ "@entity-access/server-pages": "^1.1.404",
26
26
  "@ffmpeg/core-mt": "^0.12.6",
27
27
  "@ffmpeg/ffmpeg": "^0.12.10",
28
28
  "@ffmpeg/util": "^0.12.1",
package/src/WebServer.ts CHANGED
@@ -49,7 +49,6 @@ import { fileAccessTypes } from "./server/model/entities/AppFile.js";
49
49
  import EntityContext from "@entity-access/entity-access/dist/model/EntityContext.js";
50
50
  import AppKeyProvider from "./server/services/AppKeyProvider.js";
51
51
  import KeyProvider from "@entity-access/server-pages/dist/services/KeyProvider.js";
52
- import GlobalEvents from "./common/GlobalEvents.js";
53
52
  import SessionSecurity from "@entity-access/server-pages/dist/services/SessionSecurity.js";
54
53
  import RootCertificates from "./server/services/root-certs/RootCertificates.js";
55
54
  import TlsSessionKeys from "./common/tls/TlsSessionKeys.js";
@@ -117,8 +116,6 @@ export default class WebServer {
117
116
  globalServices.resolve(WorkflowContext);
118
117
  globalServices.resolve(CertificateStore).folder = "/data/certs";
119
118
 
120
- globalServices.resolve(GlobalEvents).startListener();
121
-
122
119
  try {
123
120
 
124
121
  if (seedDb) {
@@ -1,249 +1,249 @@
1
- /* eslint-disable no-console */
2
- import { RegisterSingleton } from "@entity-access/entity-access/dist/di/di.js";
3
- import cluster from "cluster";
4
- import { existsSync, unlinkSync } from "fs";
5
- import { platform } from "os";
6
- import { isMainThread } from "worker_threads";
7
- import { WebSocketServer, WebSocket, } from "ws";
8
-
9
- const socketPath = /win32/i.test(platform()) ? `\\\\.\\pipe\\social-mail-ipc-sock.sock` : `/tmp/social-mail-ipc-sock.sock`;
10
-
11
- let pid = 1;
12
-
13
- @RegisterSingleton
14
- export default class GlobalEvents {
15
-
16
- // eslint-disable-next-line @typescript-eslint/ban-types
17
- private listeners = new Map<string, Function[]>();
18
-
19
- private client: Promise<WebSocket>;
20
-
21
- public on(m: "refresh-dns", fx: (m1: "refresh-dns", value: { serverID }) => any);
22
- public on(m: "dkim-added", fx: (m1: "dkim-added", value: { serverID, host, publicKey, name, keyType }) => any);
23
- public on(m: "host-added", fx: (m1: "host-added", value: { serverID, host: string }) => any);
24
- public on(m: "html-to-image" | "html-to-image-result", value: any);
25
- public on(message: any, value: (msg: any, data:any) => any) {
26
- let list = this.listeners.get(message);
27
- if(!list) {
28
- list = [];
29
- this.listeners.set(message, list);
30
- }
31
- list.push(value);
32
- this.connectClient().catch(console.error);
33
- return {
34
- [Symbol.dispose]: () => {
35
- const index = list.indexOf(value);
36
- if (index !== -1) {
37
- list.splice(index, 1);
38
- }
39
- }
40
- };
41
- }
42
-
43
- public onPost(m: "html-to-image", fx: (v) => Promise<any>) {
44
- this.on(m, (m1, v) => {
45
- const { id } = v;
46
- try {
47
- fx(v).then(
48
- (value) => this.notify(id, { value } as any),
49
- (error) => this.notify(id, { error } as any));
50
- } catch (e) {
51
- this.notify(id, { error: e} as any);
52
- }
53
- });
54
- }
55
-
56
- public post(m: "html-to-image", value: any): Promise<any>;
57
- public async post(m: any, p: any): Promise<any> {
58
- const id = `${m}-${pid++}`;
59
- return new Promise<any>((resolve, reject) => {
60
- const d = this.on("html-to-image", ({ value, error }) => {
61
- d[Symbol.dispose]();
62
- if (error) {
63
- reject(error);
64
- } else {
65
- resolve(value);
66
- }
67
- });
68
- p.id = id;
69
- this.notify(m, p);
70
- });
71
- }
72
-
73
- public notify(m: "refresh-dns", value: { serverID });
74
- public notify(m: "dkim-added", value: { serverID, host, publicKey, name, keyType });
75
- public notify(m: "host-added", value: { serverID, host: string });
76
- public notify(message: any, value: any) {
77
- this.notifyInternal(message, value).catch(console.error);
78
- }
79
-
80
- startListener() {
81
- if(!cluster.isPrimary) {
82
- return;
83
- }
84
- if(!isMainThread) {
85
- return;
86
- }
87
- this.startListenerInternal().catch(console.error);
88
- }
89
-
90
- private async notifyInternal(message: string, value: string) {
91
- try {
92
- const client = await this.connectClient();
93
- const json = JSON.stringify({ message, value });
94
- const data = Buffer.from(json, "utf-8");
95
- client.send(data, { binary: true }, (error) => {
96
- if (error) {
97
- try {
98
- client.close();
99
- } catch {
100
- // do nothing
101
- }
102
- this.client = null;
103
- return;
104
- }
105
- });
106
- // console.log(`Notify success ${json}`);
107
- } catch (error) {
108
- console.error(error);
109
- this.client?.then((c) => {
110
- try {
111
- c.close();
112
- } catch {
113
- // do nothing
114
- }
115
- this.client = null;
116
- }).catch(console.error);
117
- this.client = null;
118
- }
119
- }
120
-
121
- private connectClient() {
122
- this.client ??= (async () => {
123
- let client: WebSocket;
124
- try {
125
- client = await new Promise((resolve, reject) => {
126
- const s = new WebSocket(`ws+unix://${socketPath}`);
127
- s.on("open", () => resolve(s));
128
- s.on("error", reject);
129
- });
130
- client.on("error", (err) => {
131
- console.error(err);
132
- this.client = null;
133
- });
134
- client.on("end", () => {
135
- this.client = null;
136
- });
137
- client.on("close", () => {
138
- this.client = null;
139
- });
140
- } catch (error) {
141
- console.error(`No socket is listening on ${socketPath}`);
142
- console.error(error.stack ?? error.toString());
143
- this.client = null;
144
- }
145
-
146
- // start listening...
147
- client.on("message", (data: Buffer, isBinary ) => {
148
- const text = data.toString("utf-8");
149
- // console.log(`Received ${text}`);
150
- const { message, value } = JSON.parse(text);
151
- const list = this.listeners.get(message);
152
- if (!list) {
153
- return;
154
- }
155
- for (const iterator of list) {
156
- iterator(message, value)?.catch(console.error);
157
- }
158
- });
159
- return client;
160
- })();
161
- return this.client;
162
- }
163
-
164
- private async startListenerInternal() {
165
- try {
166
- if(existsSync(socketPath)) {
167
- unlinkSync(socketPath);
168
- }
169
-
170
- const server = new WebSocketServer({
171
- port: socketPath as any,
172
- }, () => {
173
- console.log(`Global Events listening on ${socketPath}`);
174
- });
175
- server.on("connection", (socket) => {
176
- socket.on("message", (data, binary) => {
177
- for (const iterator of server.clients) {
178
- iterator.send(data, { binary }, (error) => {
179
- if (error) {
180
- try { iterator.close(); } catch {
181
- // so nothing
182
- }
183
- }
184
- });
185
- }
186
- });
187
- });
188
- server.on("error", console.error);
189
-
190
- } catch (error) {
191
- console.error(error);
192
- }
193
- }
194
-
195
- // private async writeToClient(key: Socket,text: Buffer, promise: Promise<void>): Promise<void> {
196
- // await promise;
197
- // try {
198
- // await new Promise<void>((resolve, reject) => {
199
- // key.write(text, (error) => {
200
- // if (error) {
201
- // reject(error);
202
- // return;
203
- // }
204
- // resolve();
205
- // });
206
- // });
207
- // } catch (error) {
208
- // try {
209
- // key.end();
210
- // } catch {
211
- // // closing errored socket...
212
- // }
213
- // this.serverClients.delete(key);
214
- // }
215
- // }
216
-
217
- }
218
-
219
- export class TestGlobalEvents extends GlobalEvents {
220
- // eslint-disable-next-line @typescript-eslint/ban-types
221
- map = new Map<string, Function[]>();
222
- on(m, fx){
223
- const { map } = this;
224
- let list = map.get(m);
225
- if(!list) {
226
- list = [];
227
- map.set(m, list);
228
- }
229
- list.push(fx);
230
- return {
231
- [Symbol.dispose]() {
232
- // do nothing
233
- }
234
- };
235
- }
236
- notify(m, v) {
237
- const { map } = this;
238
- const list = map.get(m);
239
- if(!list) {
240
- return list;
241
- }
242
- for (const iterator of list) {
243
- iterator(m, v)?.catch(console.error);
244
- }
245
- }
246
- startListener() {
247
- return Promise.resolve();
248
- }
249
- }
1
+ // /* eslint-disable no-console */
2
+ // import { RegisterSingleton } from "@entity-access/entity-access/dist/di/di.js";
3
+ // import cluster from "cluster";
4
+ // import { existsSync, unlinkSync } from "fs";
5
+ // import { platform } from "os";
6
+ // import { isMainThread } from "worker_threads";
7
+ // import { WebSocketServer, WebSocket, } from "ws";
8
+
9
+ // const socketPath = /win32/i.test(platform()) ? `\\\\.\\pipe\\social-mail-ipc-sock.sock` : `/tmp/social-mail-ipc-sock.sock`;
10
+
11
+ // let pid = 1;
12
+
13
+ // @RegisterSingleton
14
+ // export default class GlobalEvents {
15
+
16
+ // // eslint-disable-next-line @typescript-eslint/ban-types
17
+ // private listeners = new Map<string, Function[]>();
18
+
19
+ // private client: Promise<WebSocket>;
20
+
21
+ // public on(m: "refresh-dns", fx: (m1: "refresh-dns", value: { serverID }) => any);
22
+ // public on(m: "dkim-added", fx: (m1: "dkim-added", value: { serverID, host, publicKey, name, keyType }) => any);
23
+ // public on(m: "host-added", fx: (m1: "host-added", value: { serverID, host: string }) => any);
24
+ // public on(m: "html-to-image" | "html-to-image-result", value: any);
25
+ // public on(message: any, value: (msg: any, data:any) => any) {
26
+ // let list = this.listeners.get(message);
27
+ // if(!list) {
28
+ // list = [];
29
+ // this.listeners.set(message, list);
30
+ // }
31
+ // list.push(value);
32
+ // this.connectClient().catch(console.error);
33
+ // return {
34
+ // [Symbol.dispose]: () => {
35
+ // const index = list.indexOf(value);
36
+ // if (index !== -1) {
37
+ // list.splice(index, 1);
38
+ // }
39
+ // }
40
+ // };
41
+ // }
42
+
43
+ // public onPost(m: "html-to-image", fx: (v) => Promise<any>) {
44
+ // this.on(m, (m1, v) => {
45
+ // const { id } = v;
46
+ // try {
47
+ // fx(v).then(
48
+ // (value) => this.notify(id, { value } as any),
49
+ // (error) => this.notify(id, { error } as any));
50
+ // } catch (e) {
51
+ // this.notify(id, { error: e} as any);
52
+ // }
53
+ // });
54
+ // }
55
+
56
+ // public post(m: "html-to-image", value: any): Promise<any>;
57
+ // public async post(m: any, p: any): Promise<any> {
58
+ // const id = `${m}-${pid++}`;
59
+ // return new Promise<any>((resolve, reject) => {
60
+ // const d = this.on("html-to-image", ({ value, error }) => {
61
+ // d[Symbol.dispose]();
62
+ // if (error) {
63
+ // reject(error);
64
+ // } else {
65
+ // resolve(value);
66
+ // }
67
+ // });
68
+ // p.id = id;
69
+ // this.notify(m, p);
70
+ // });
71
+ // }
72
+
73
+ // public notify(m: "refresh-dns", value: { serverID });
74
+ // public notify(m: "dkim-added", value: { serverID, host, publicKey, name, keyType });
75
+ // public notify(m: "host-added", value: { serverID, host: string });
76
+ // public notify(message: any, value: any) {
77
+ // this.notifyInternal(message, value).catch(console.error);
78
+ // }
79
+
80
+ // startListener() {
81
+ // if(!cluster.isPrimary) {
82
+ // return;
83
+ // }
84
+ // if(!isMainThread) {
85
+ // return;
86
+ // }
87
+ // this.startListenerInternal().catch(console.error);
88
+ // }
89
+
90
+ // private async notifyInternal(message: string, value: string) {
91
+ // try {
92
+ // const client = await this.connectClient();
93
+ // const json = JSON.stringify({ message, value });
94
+ // const data = Buffer.from(json, "utf-8");
95
+ // client.send(data, { binary: true }, (error) => {
96
+ // if (error) {
97
+ // try {
98
+ // client.close();
99
+ // } catch {
100
+ // // do nothing
101
+ // }
102
+ // this.client = null;
103
+ // return;
104
+ // }
105
+ // });
106
+ // // console.log(`Notify success ${json}`);
107
+ // } catch (error) {
108
+ // console.error(error);
109
+ // this.client?.then((c) => {
110
+ // try {
111
+ // c.close();
112
+ // } catch {
113
+ // // do nothing
114
+ // }
115
+ // this.client = null;
116
+ // }).catch(console.error);
117
+ // this.client = null;
118
+ // }
119
+ // }
120
+
121
+ // private connectClient() {
122
+ // this.client ??= (async () => {
123
+ // let client: WebSocket;
124
+ // try {
125
+ // client = await new Promise((resolve, reject) => {
126
+ // const s = new WebSocket(`ws+unix://${socketPath}`);
127
+ // s.on("open", () => resolve(s));
128
+ // s.on("error", reject);
129
+ // });
130
+ // client.on("error", (err) => {
131
+ // console.error(err);
132
+ // this.client = null;
133
+ // });
134
+ // client.on("end", () => {
135
+ // this.client = null;
136
+ // });
137
+ // client.on("close", () => {
138
+ // this.client = null;
139
+ // });
140
+ // } catch (error) {
141
+ // console.error(`No socket is listening on ${socketPath}`);
142
+ // console.error(error.stack ?? error.toString());
143
+ // this.client = null;
144
+ // }
145
+
146
+ // // start listening...
147
+ // client.on("message", (data: Buffer, isBinary ) => {
148
+ // const text = data.toString("utf-8");
149
+ // // console.log(`Received ${text}`);
150
+ // const { message, value } = JSON.parse(text);
151
+ // const list = this.listeners.get(message);
152
+ // if (!list) {
153
+ // return;
154
+ // }
155
+ // for (const iterator of list) {
156
+ // iterator(message, value)?.catch(console.error);
157
+ // }
158
+ // });
159
+ // return client;
160
+ // })();
161
+ // return this.client;
162
+ // }
163
+
164
+ // private async startListenerInternal() {
165
+ // try {
166
+ // if(existsSync(socketPath)) {
167
+ // unlinkSync(socketPath);
168
+ // }
169
+
170
+ // const server = new WebSocketServer({
171
+ // port: socketPath as any,
172
+ // }, () => {
173
+ // console.log(`Global Events listening on ${socketPath}`);
174
+ // });
175
+ // server.on("connection", (socket) => {
176
+ // socket.on("message", (data, binary) => {
177
+ // for (const iterator of server.clients) {
178
+ // iterator.send(data, { binary }, (error) => {
179
+ // if (error) {
180
+ // try { iterator.close(); } catch {
181
+ // // so nothing
182
+ // }
183
+ // }
184
+ // });
185
+ // }
186
+ // });
187
+ // });
188
+ // server.on("error", console.error);
189
+
190
+ // } catch (error) {
191
+ // console.error(error);
192
+ // }
193
+ // }
194
+
195
+ // // private async writeToClient(key: Socket,text: Buffer, promise: Promise<void>): Promise<void> {
196
+ // // await promise;
197
+ // // try {
198
+ // // await new Promise<void>((resolve, reject) => {
199
+ // // key.write(text, (error) => {
200
+ // // if (error) {
201
+ // // reject(error);
202
+ // // return;
203
+ // // }
204
+ // // resolve();
205
+ // // });
206
+ // // });
207
+ // // } catch (error) {
208
+ // // try {
209
+ // // key.end();
210
+ // // } catch {
211
+ // // // closing errored socket...
212
+ // // }
213
+ // // this.serverClients.delete(key);
214
+ // // }
215
+ // // }
216
+
217
+ // }
218
+
219
+ // export class TestGlobalEvents extends GlobalEvents {
220
+ // // eslint-disable-next-line @typescript-eslint/ban-types
221
+ // map = new Map<string, Function[]>();
222
+ // on(m, fx){
223
+ // const { map } = this;
224
+ // let list = map.get(m);
225
+ // if(!list) {
226
+ // list = [];
227
+ // map.set(m, list);
228
+ // }
229
+ // list.push(fx);
230
+ // return {
231
+ // [Symbol.dispose]() {
232
+ // // do nothing
233
+ // }
234
+ // };
235
+ // }
236
+ // notify(m, v) {
237
+ // const { map } = this;
238
+ // const list = map.get(m);
239
+ // if(!list) {
240
+ // return list;
241
+ // }
242
+ // for (const iterator of list) {
243
+ // iterator(m, v)?.catch(console.error);
244
+ // }
245
+ // }
246
+ // startListener() {
247
+ // return Promise.resolve();
248
+ // }
249
+ // }
@@ -76,6 +76,17 @@ export const globalEnv = {
76
76
  user: process.env.SOCIAL_MAIL_DB_USER ?? "postgres",
77
77
  password: process.env.SOCIAL_MAIL_DB_PASSWORD ?? "abcd123",
78
78
  },
79
+
80
+ pgEvents: {
81
+ server: process.env.SOCIAL_MAIL_EVENTS_DB_SERVER ?? process.env.SOCIAL_MAIL_DB_SERVER ?? "postgres",
82
+ database: process.env.SOCIAL_MAIL_EVENTS_DB_DATABASE ?? process.env.SOCIAL_MAIL_DB_DATABASE ?? "SocialMails",
83
+ host: process.env.SOCIAL_MAIL_EVENTS_DB_HOST ?? process.env.SOCIAL_MAIL_DB_HOST ?? "localhost",
84
+ port: Number(process.env.SOCIAL_MAIL_EVENTS_DB_PORT ?? process.env.SOCIAL_MAIL_DB_PORT ?? 5432),
85
+ ssl: JSON.parse(process.env.SOCIAL_MAIL_EVENTS_DB_SSL ?? process.env.SOCIAL_MAIL_DB_SSL ?? "true"),
86
+ user: process.env.SOCIAL_MAIL_EVENTS_DB_USER ?? process.env.SOCIAL_MAIL_DB_USER ?? "postgres",
87
+ password: process.env.SOCIAL_MAIL_EVENTS_DB_PASSWORD ?? process.env.SOCIAL_MAIL_DB_PASSWORD ?? "abcd123",
88
+ },
89
+
79
90
  numCPUs: isTestMode
80
91
  ? 2
81
92
  : (process.env.SOCIAL_MAIL_CLUSTER_WORKERS
@@ -6,8 +6,6 @@ import Inject, { ServiceProvider } from "@entity-access/entity-access/dist/di/di
6
6
  import CryptoService from "../../services/CryptoService.js";
7
7
  import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
8
8
  import SocialMailContext from "../SocialMailContext.js";
9
- import GlobalEvents from "../../../common/GlobalEvents.js";
10
- import { globalEnv } from "../../../common/globalEnv.js";
11
9
  import WorkflowContext from "@entity-access/entity-access/dist/workflows/WorkflowContext.js";
12
10
  import SyncDnsZoneRecordsWorkflow from "../../workflows/dns/SyncDnsZoneRecordsWorkflow.js";
13
11
 
@@ -19,9 +17,6 @@ export default class DomainKeyEvents extends AuthenticatedEvents<DomainKey> {
19
17
  @Inject
20
18
  private db: SocialMailContext;
21
19
 
22
- @Inject
23
- private globalEvents: GlobalEvents;
24
-
25
20
  filter(query: IEntityQuery<DomainKey>): IEntityQuery<DomainKey> {
26
21
  if (this.verify) {
27
22
  this.sessionUser.ensureLoggedIn();
@@ -4,7 +4,6 @@ import { IEntityQuery } from "@entity-access/entity-access/dist/model/IFilterWit
4
4
  import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
5
5
  import WorkflowContext from "@entity-access/entity-access/dist/workflows/WorkflowContext.js";
6
6
  import ApexDomain from "../../../common/ApexDomain.js";
7
- import GlobalEvents from "../../../common/GlobalEvents.js";
8
7
  import EmailAddressService from "../../services/EmailAddressService.js";
9
8
  import SyncDnsZoneRecordsWorkflow from "../../workflows/dns/SyncDnsZoneRecordsWorkflow.js";
10
9
  import { WebSiteHost } from "../entities/WebSiteHost.js";
@@ -12,9 +11,6 @@ import AuthenticatedEvents from "./AuthenticatedEvents.js";
12
11
 
13
12
  export class WebSiteHostEvents extends AuthenticatedEvents<WebSiteHost> {
14
13
 
15
- @Inject
16
- private globalEvents: GlobalEvents;
17
-
18
14
  filter(query: IEntityQuery<WebSiteHost>) {
19
15
  if (this.sessionUser.isAdmin) {
20
16
  return query;
@@ -0,0 +1,43 @@
1
+ /* eslint-disable no-console */
2
+ import Inject, { RegisterSingleton, ServiceObject } from "@entity-access/entity-access/dist/di/di.js";
3
+ import PgEvents from "./PgEvents.js";
4
+ import { globalEnv } from "../../../common/globalEnv.js";
5
+
6
+ export interface IMessageChannel<T = string> {
7
+ on(fx: (name: string, data: T) => any);
8
+ notify(data: T);
9
+ }
10
+
11
+ @RegisterSingleton
12
+ export default class MessagingService extends ServiceObject {
13
+
14
+ channelRefresh: IMessageChannel;
15
+
16
+ refreshDns: IMessageChannel<{ serverID }>;
17
+
18
+ @Inject
19
+ private pgEvents: PgEvents;
20
+
21
+ postInit() {
22
+ this.channelRefresh = this.segment(`web-site-channel-host-clear-${globalEnv.serverID}`);
23
+ this.refreshDns = this.segment("refresh-dns");
24
+ }
25
+
26
+ notify(messageName: string, data: any): any {
27
+ return this.pgEvents.emit(messageName, JSON.stringify(data ?? ""));
28
+ }
29
+
30
+ listen(messageName: string, fx: (name: string, data: any) => any): any {
31
+ return this.pgEvents.listen(messageName, (msg, data) => {
32
+ return fx(msg, JSON.parse(data));
33
+ });
34
+ }
35
+
36
+ private segment(messageName: string): IMessageChannel<any> {
37
+ return {
38
+ on: (fx) => this.listen(messageName, (data) => fx(messageName, data)?.catch?.(console.error)),
39
+ notify: (data) => this.notify(messageName, data)?.catch?.(console.error),
40
+ };
41
+ }
42
+
43
+ }