@social-mail/social-mail-web-server 1.8.465 → 1.8.466
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/dist/WebCluster.d.ts.map +1 -1
- package/dist/WebCluster.js +0 -32
- package/dist/WebCluster.js.map +1 -1
- package/dist/common/ApexDomain.js +1 -1
- package/dist/common/ApexDomain.js.map +1 -1
- package/dist/server/model/entities/WebSite.d.ts +4 -0
- package/dist/server/model/entities/WebSite.d.ts.map +1 -1
- package/dist/server/model/entities/WebSite.js +9 -0
- package/dist/server/model/entities/WebSite.js.map +1 -1
- package/dist/server/seed/ui/seed-ui.js +1 -1
- package/dist/server/seed/ui/seed-ui.js.map +1 -1
- package/dist/server/services/encryption/EncryptionService.d.ts +3 -2
- package/dist/server/services/encryption/EncryptionService.d.ts.map +1 -1
- package/dist/server/services/encryption/EncryptionService.js +2 -2
- package/dist/server/services/encryption/EncryptionService.js.map +1 -1
- package/dist/server/services/files/FileVersionService.js +1 -1
- package/dist/server/services/files/FileVersionService.js.map +1 -1
- package/dist/server/services/files/ISiteFolder.d.ts +4 -0
- package/dist/server/services/files/ISiteFolder.d.ts.map +1 -1
- package/dist/server/services/files/WebSiteContentService.d.ts +5 -2
- package/dist/server/services/files/WebSiteContentService.d.ts.map +1 -1
- package/dist/server/services/files/WebSiteContentService.js +65 -17
- package/dist/server/services/files/WebSiteContentService.js.map +1 -1
- package/dist/server/services/html/HtmlForEmailService.d.ts +6 -0
- package/dist/server/services/html/HtmlForEmailService.d.ts.map +1 -1
- package/dist/server/services/html/HtmlForEmailService.js +10 -0
- package/dist/server/services/html/HtmlForEmailService.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/wwwroot/routes/index.d.ts.map +1 -1
- package/dist/wwwroot/routes/index.js.map +1 -1
- package/dist/wwwroot/routes/social-mail/site/draft-url/[siteID]/get.d.ts +12 -0
- package/dist/wwwroot/routes/social-mail/site/draft-url/[siteID]/get.d.ts.map +1 -0
- package/dist/wwwroot/routes/social-mail/site/draft-url/[siteID]/get.js +57 -0
- package/dist/wwwroot/routes/social-mail/site/draft-url/[siteID]/get.js.map +1 -0
- package/package.json +1 -1
- package/src/WebCluster.ts +0 -36
- package/src/common/ApexDomain.ts +1 -1
- package/src/server/model/entities/WebSite.ts +8 -0
- package/src/server/seed/ui/seed-ui.ts +1 -1
- package/src/server/services/encryption/EncryptionService.ts +2 -2
- package/src/server/services/files/FileVersionService.ts +1 -1
- package/src/server/services/files/ISiteFolder.ts +4 -0
- package/src/server/services/files/WebSiteContentService.ts +77 -18
- package/src/server/services/html/HtmlForEmailService.ts +12 -1
- package/src/wwwroot/routes/index.tsx +1 -0
- package/src/wwwroot/routes/social-mail/site/draft-url/[siteID]/get.tsx +48 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/wwwroot/routes/index.tsx"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,mCAAmC,CAAC;AAGzD,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAG5D,OAAO,qBAAqB,MAAM,sDAAsD,CAAC;AAIzF,OAAO,mBAAmB,MAAM,mDAAmD,CAAC;AAEpF,MAAM,CAAC,OAAO,MAAO,SAAQ,IAAI;IAG7B,MAAM,EAAE,QAAQ,CAAC;IAGjB,kBAAkB,EAAE,qBAAqB,CAAC;IAG1C,YAAY,EAAE,mBAAmB,CAAC;IAElC,GAAG,EAAE,GAAG,CAAC;IAEH,GAAG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/wwwroot/routes/index.tsx"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,mCAAmC,CAAC;AAGzD,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAG5D,OAAO,qBAAqB,MAAM,sDAAsD,CAAC;AAIzF,OAAO,mBAAmB,MAAM,mDAAmD,CAAC;AAEpF,MAAM,CAAC,OAAO,MAAO,SAAQ,IAAI;IAG7B,MAAM,EAAE,QAAQ,CAAC;IAGjB,kBAAkB,EAAE,qBAAqB,CAAC;IAG1C,YAAY,EAAE,mBAAmB,CAAC;IAElC,GAAG,EAAE,GAAG,CAAC;IAEH,GAAG;CAgJZ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/wwwroot/routes/index.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,+BAA+B;AAC/B,OAAO,MAAM,MAAM,4CAA4C,CAAC;AAChE,OAAO,QAAQ,MAAM,mCAAmC,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAC;AACzF,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAC5E,OAAO,SAAS,MAAM,2BAA2B,CAAC;AAClD,OAAO,qBAAqB,MAAM,sDAAsD,CAAC;AACzF,OAAO,gBAAgB,MAAM,gDAAgD,CAAC;AAC9E,OAAO,KAAK,MAAM,uBAAuB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,mBAAmB,MAAM,mDAAmD,CAAC;AAEpF,MAAM,CAAC,OAAO,gBAAO,SAAQ,IAAI;IAa7B,KAAK,CAAC,GAAG;QAEL,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAErC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAE/B,kDAAkD;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;QAC7E,IAAI,OAAO,EAAE,CAAC;YACV,+BAA+B;YAC/B,2CAA2C;YAE3C,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC;YAE7C,IAAI,QAAQ,GAAG,KAAK,CAAC;YAErB,IAAI,IAAI,GAAG,CAAE,GAAI,IAAI,CAAC,SAAS,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;YAC1B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/wwwroot/routes/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
2
|
+
import SocialMailContext from "../../../../../../server/model/SocialMailContext.js";
|
|
3
|
+
import ReplicaReader from "../../../../../../server/services/replica/ReplicaReader.js";
|
|
4
|
+
import EncryptionService from "../../../../../../server/services/encryption/EncryptionService.js";
|
|
5
|
+
export default class extends Page {
|
|
6
|
+
siteID: any;
|
|
7
|
+
db: SocialMailContext;
|
|
8
|
+
ecs: EncryptionService;
|
|
9
|
+
replicaReader: ReplicaReader;
|
|
10
|
+
run(): Promise<import("@entity-access/server-pages/dist/Content.js").Redirect>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=get.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../../../../../src/wwwroot/routes/social-mail/site/draft-url/[siteID]/get.tsx"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,iBAAiB,MAAM,qDAAqD,CAAC;AAEpF,OAAO,aAAa,MAAM,4DAA4D,CAAC;AAGvF,OAAO,iBAAiB,MAAM,mEAAmE,CAAC;AAIlG,MAAM,CAAC,OAAO,MAAO,SAAQ,IAAI;IAG7B,MAAM,MAAC;IAGP,EAAE,EAAE,iBAAiB,CAAC;IAGtB,GAAG,EAAE,iBAAiB,CAAC;IAGvB,aAAa,EAAE,aAAa,CAAC;IAEvB,GAAG;CAqBZ"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
11
|
+
import { Route } from "@entity-access/server-pages/dist/core/Route.js";
|
|
12
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
13
|
+
import SocialMailContext from "../../../../../../server/model/SocialMailContext.js";
|
|
14
|
+
import { Prepare } from "@entity-access/server-pages/dist/decorators/Prepare.js";
|
|
15
|
+
import ReplicaReader from "../../../../../../server/services/replica/ReplicaReader.js";
|
|
16
|
+
import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
|
|
17
|
+
import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
|
|
18
|
+
import EncryptionService from "../../../../../../server/services/encryption/EncryptionService.js";
|
|
19
|
+
import { globalEnv } from "../../../../../../common/globalEnv.js";
|
|
20
|
+
let default_1 = class extends Page {
|
|
21
|
+
async run() {
|
|
22
|
+
const site = await this.replicaReader.query((db) => db.websiteFolders.filtered("read").where(this, (p) => (x) => x.folderID === p.siteID)
|
|
23
|
+
.first());
|
|
24
|
+
if (!site) {
|
|
25
|
+
throw new EntityAccessError("Site not found");
|
|
26
|
+
}
|
|
27
|
+
const time = site.lastModified ? DateTime.from(site.lastModified) : DateTime.now;
|
|
28
|
+
let path = this.childPath.join("/");
|
|
29
|
+
if (!path) {
|
|
30
|
+
path = "index.html";
|
|
31
|
+
}
|
|
32
|
+
const encoded = this.ecs.general.encrypt(`${site.folderID.toString(36)}-${time.msSinceEpoch.toString(36)}`, "hex");
|
|
33
|
+
const host = `${globalEnv.serverID}-${encoded}`;
|
|
34
|
+
return this.redirect(`https://${host}.sites.${globalEnv.wildcardDomain}/${path}`);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
__decorate([
|
|
38
|
+
Route("siteID"),
|
|
39
|
+
__metadata("design:type", Object)
|
|
40
|
+
], default_1.prototype, "siteID", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
Inject,
|
|
43
|
+
__metadata("design:type", SocialMailContext)
|
|
44
|
+
], default_1.prototype, "db", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
Inject,
|
|
47
|
+
__metadata("design:type", EncryptionService)
|
|
48
|
+
], default_1.prototype, "ecs", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
Inject,
|
|
51
|
+
__metadata("design:type", ReplicaReader)
|
|
52
|
+
], default_1.prototype, "replicaReader", void 0);
|
|
53
|
+
default_1 = __decorate([
|
|
54
|
+
Prepare.authorize
|
|
55
|
+
], default_1);
|
|
56
|
+
export default default_1;
|
|
57
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../../../../../src/wwwroot/routes/social-mail/site/draft-url/[siteID]/get.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,MAAM,MAAM,4CAA4C,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,gDAAgD,CAAC;AACvE,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,iBAAiB,MAAM,qDAAqD,CAAC;AACpF,OAAO,EAAE,OAAO,EAAE,MAAM,wDAAwD,CAAC;AACjF,OAAO,aAAa,MAAM,4DAA4D,CAAC;AACvF,OAAO,iBAAiB,MAAM,+DAA+D,CAAC;AAC9F,OAAO,QAAQ,MAAM,qDAAqD,CAAC;AAC3E,OAAO,iBAAiB,MAAM,mEAAmE,CAAC;AAClG,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAGnD,gBAAA,KAAM,SAAQ,IAAI;IAc7B,KAAK,CAAC,GAAG;QAEL,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,MAAM,CAAC;aACpI,KAAK,EAAE,CAAC,CAAC;QAEd,IAAG,CAAC,IAAI,EAAE,CAAC;YACP,MAAM,IAAI,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;QAEjF,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,IAAG,CAAC,IAAI,EAAE,CAAC;YACP,IAAI,GAAG,YAAY,CAAC;QACxB,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACnH,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC,QAAQ,IAAI,OAAO,EAAE,CAAC;QAEhD,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,UAAU,SAAS,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC,CAAC;IACtF,CAAC;CACJ,CAAA;AAhCG;IADC,KAAK,CAAC,QAAQ,CAAC;;yCACT;AAGP;IADC,MAAM;8BACH,iBAAiB;qCAAC;AAGtB;IADC,MAAM;8BACF,iBAAiB;sCAAC;AAGvB;IADC,MAAM;8BACQ,aAAa;gDAAC;AAZlB;IADd,OAAO,CAAC,SAAS;aAoCjB"}
|
package/package.json
CHANGED
package/src/WebCluster.ts
CHANGED
|
@@ -1,43 +1,10 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import sleep from './common/sleep.js';
|
|
3
3
|
import WebServer from './WebServer.js';
|
|
4
|
-
import { spawn } from 'node:child_process';
|
|
5
4
|
import ClusterInstance, { RecycledWorker } from "@entity-access/server-pages/dist/ClusterInstance.js";
|
|
6
5
|
import { globalEnv } from './common/globalEnv.js';
|
|
7
6
|
import Tracer from './Tracer.js';
|
|
8
7
|
|
|
9
|
-
const scanViaClamAV = (globalEnv.av?.type ?? "ClamAV") === "ClamAV";
|
|
10
|
-
|
|
11
|
-
const spawnPromise = (path, args?: string[]) => new Promise<number>((resolve, reject) => {
|
|
12
|
-
const cd = spawn(path, args);
|
|
13
|
-
cd.stdout.on("data", (data) => {
|
|
14
|
-
console.log(`${path}: ${data}`);
|
|
15
|
-
});
|
|
16
|
-
cd.stderr.on("data", (data) => {
|
|
17
|
-
console.error(`${path}: ${data}`);
|
|
18
|
-
});
|
|
19
|
-
cd.on("close", resolve);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const spawnLoop = (everySeconds: number, path, args?: string[]) => {
|
|
23
|
-
const run = async () => {
|
|
24
|
-
const everyMS = everySeconds * 1000;
|
|
25
|
-
while(true) {
|
|
26
|
-
await spawnPromise(path, args);
|
|
27
|
-
console.log(`${path} closed, restarting in ${everySeconds} seconds`);
|
|
28
|
-
await sleep(everyMS);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
run().catch(console.error);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const runClamD = async () => {
|
|
35
|
-
spawnLoop(15, "clamd");
|
|
36
|
-
// we need to wait 20 seconds approx to let clamD start properly.
|
|
37
|
-
await sleep(30000);
|
|
38
|
-
spawnLoop(60*60*24, "freshclam");
|
|
39
|
-
};
|
|
40
|
-
|
|
41
8
|
const numCPUs = globalEnv.numCPUs;
|
|
42
9
|
|
|
43
10
|
export default class WebCluster extends ClusterInstance<typeof WebServer> {
|
|
@@ -50,9 +17,6 @@ export default class WebCluster extends ClusterInstance<typeof WebServer> {
|
|
|
50
17
|
protected async runPrimary(arg: typeof WebServer) {
|
|
51
18
|
|
|
52
19
|
Tracer.instance.bindConsole();
|
|
53
|
-
if (scanViaClamAV) {
|
|
54
|
-
runClamD().catch(console.error);
|
|
55
|
-
}
|
|
56
20
|
|
|
57
21
|
// seed...
|
|
58
22
|
const ws = new arg();
|
package/src/common/ApexDomain.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type { WebSiteChannel } from "./WebSiteChannel.js";
|
|
|
19
19
|
import type { WebSiteVersion } from "./WebSiteVersion.js";
|
|
20
20
|
import type { WebSiteHost } from "./WebSiteHost.js";
|
|
21
21
|
import type WebSiteTag from "./WebSiteTag.js";
|
|
22
|
+
import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Index Designs...
|
|
@@ -101,9 +102,13 @@ export default class WebSite {
|
|
|
101
102
|
@Column({ dataType: "Boolean", default:() => true })
|
|
102
103
|
public isStatic: boolean;
|
|
103
104
|
|
|
105
|
+
/** Is this website used as a template for other website? */
|
|
104
106
|
@Column({ dataType: "Boolean", default:() => false })
|
|
105
107
|
public isTemplate: boolean;
|
|
106
108
|
|
|
109
|
+
@Column({ dataType: "Boolean", default:() => false })
|
|
110
|
+
public hasEmailTemplates?: boolean;
|
|
111
|
+
|
|
107
112
|
@Column({ dataType: "Boolean", default:() => false })
|
|
108
113
|
public isDesign: boolean;
|
|
109
114
|
|
|
@@ -139,6 +144,9 @@ export default class WebSite {
|
|
|
139
144
|
@Column({ dataType: "Boolean", default: () => false })
|
|
140
145
|
public isModified: boolean;
|
|
141
146
|
|
|
147
|
+
@Column({ dataType: "DateTime", nullable: true })
|
|
148
|
+
public lastModified: DateTime;
|
|
149
|
+
|
|
142
150
|
@Column({ dataType:"BigInt", default: () => 0})
|
|
143
151
|
public snapshotStorage: number;
|
|
144
152
|
|
|
@@ -17,7 +17,7 @@ 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.9.
|
|
20
|
+
version: "1.9.116"
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
await config.saveVersion(WebComponentsPackageConfig, {
|
|
@@ -13,8 +13,8 @@ export default class EncryptionService {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
general = {
|
|
16
|
-
encrypt: (text: string) => this.encrypt(text, globalEnv.publicKey,
|
|
17
|
-
decrypt: (text: string) => this.decrypt(text, globalEnv.publicKey,
|
|
16
|
+
encrypt: (text: string, encoding: Encoding = "base64url") => this.encrypt(text, globalEnv.publicKey, encoding),
|
|
17
|
+
decrypt: (text: string, encoding: Encoding = "base64url") => this.decrypt(text, globalEnv.publicKey, encoding)
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
secure = {
|
|
@@ -42,7 +42,7 @@ export default class FileVersionService {
|
|
|
42
42
|
if ( /text\//i.test(file.contentType)) {
|
|
43
43
|
const rootFolders = file.path.split("/").filter((x) => x && x !== file.fileContentID.toString()) as any[];
|
|
44
44
|
await db.websiteFolders.where({ rootFolders }, (p) => (x) => Sql.in(x.folderID, p.rootFolders))
|
|
45
|
-
.update(void 0, (p) => (x) => ({ isModified: true }));
|
|
45
|
+
.update(void 0, (p) => (x) => ({ isModified: true, lastModified: Sql.date.now() }));
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// clean older versions...
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
export interface ISiteFolder {
|
|
2
2
|
snapshotFolderID: number;
|
|
3
|
+
host: string,
|
|
3
4
|
folderID: number;
|
|
4
5
|
eSiteID: string;
|
|
5
6
|
isTemplate: boolean;
|
|
6
7
|
isDesign: boolean;
|
|
7
8
|
remoteUrl: string;
|
|
9
|
+
cacheKey: string;
|
|
10
|
+
hasEmailTemplates: boolean;
|
|
11
|
+
draftMode: boolean;
|
|
8
12
|
}
|
|
@@ -12,6 +12,11 @@ import EncryptionService from "../encryption/EncryptionService.js";
|
|
|
12
12
|
import { hash } from "crypto";
|
|
13
13
|
import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
|
|
14
14
|
import ReplicaReader from "../replica/ReplicaReader.js";
|
|
15
|
+
import HtmlForEmailService from "../html/HtmlForEmailService.js";
|
|
16
|
+
import { Base36 } from "../../../common/Base36.js";
|
|
17
|
+
import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
|
|
18
|
+
import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
|
|
19
|
+
import type WebSite from "../../model/entities/WebSite.js";
|
|
15
20
|
|
|
16
21
|
/**
|
|
17
22
|
* We cannot read from replica as relative path can change anytime, only absolute file content id can be read from replica.
|
|
@@ -29,6 +34,9 @@ export default class WebSiteContentService
|
|
|
29
34
|
|
|
30
35
|
cache: ObjectCache<WebSiteContentService>;
|
|
31
36
|
|
|
37
|
+
@Inject
|
|
38
|
+
replicaReader: ReplicaReader;
|
|
39
|
+
|
|
32
40
|
@Inject
|
|
33
41
|
tfs: TempFileService;
|
|
34
42
|
|
|
@@ -43,17 +51,57 @@ export default class WebSiteContentService
|
|
|
43
51
|
}
|
|
44
52
|
|
|
45
53
|
@cacheFor()
|
|
46
|
-
async getCurrentSnapshotFolder(host) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
async getCurrentSnapshotFolder(host: string) {
|
|
55
|
+
|
|
56
|
+
let site: WebSite;
|
|
57
|
+
|
|
58
|
+
let draftMode = false;
|
|
59
|
+
let cacheKey: string;
|
|
60
|
+
|
|
61
|
+
// we will only decrypt site info form server-[site-info].root as the cluster may not want to
|
|
62
|
+
// lookup every website in every virtual server and no one outside cluster can route here
|
|
63
|
+
const { groups } = /^(?<sID>\d{1,16})\-(?<siteInfo>[^\.]{1,400})\.sites\./i.exec(host) ?? {};
|
|
64
|
+
const siteInfo = groups?.siteInfo;
|
|
65
|
+
if (siteInfo) {
|
|
66
|
+
let [folderID, time] = this.ecs.general.decrypt(siteInfo, "hex").split("-");
|
|
67
|
+
|
|
68
|
+
// for safety, time should not be more than 24 hours
|
|
69
|
+
folderID = Base36.decode(folderID);
|
|
70
|
+
time = Base36.decode(time);
|
|
71
|
+
const dt = DateTime.from(time);
|
|
72
|
+
if (dt.msSinceEpoch < DateTime.now.addDays(-1).msSinceEpoch) {
|
|
73
|
+
throw new EntityAccessError("Invalid draft url, please regenerate the url again");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
site = await this.replicaReader.query((db) => db.websiteFolders.where({ folderID }, (p) => (x) =>
|
|
77
|
+
x.folderID === p.folderID as any
|
|
78
|
+
&& x.isSuspended === false)
|
|
79
|
+
.first());
|
|
80
|
+
|
|
81
|
+
if (!site) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
// we need to create disk snapshot of the last time here...
|
|
87
|
+
draftMode = true;
|
|
88
|
+
cacheKey = `${site.folderID.toString(36)}-${site.lastModified ? DateTime.from(site.lastModified).msSinceEpoch.toString(36) : "z"}`;
|
|
89
|
+
|
|
90
|
+
} else {
|
|
91
|
+
site = await this.replicaReader.query((db) => db.websiteFolders.where({ host }, (p) => (x) =>
|
|
92
|
+
x.hosts.some((h) => h.host === p.host)
|
|
93
|
+
&& x.isSuspended === false)
|
|
94
|
+
.first());
|
|
95
|
+
}
|
|
51
96
|
if (!site) {
|
|
52
97
|
return null;
|
|
53
98
|
}
|
|
54
|
-
if (!site.currentVersionID) {
|
|
99
|
+
if (!draftMode && !site.currentVersionID) {
|
|
55
100
|
return null;
|
|
56
101
|
}
|
|
102
|
+
if(!draftMode) {
|
|
103
|
+
cacheKey = site.currentVersionID.toString();
|
|
104
|
+
}
|
|
57
105
|
let remoteUrl = site.remoteUrl?.trim();
|
|
58
106
|
if(remoteUrl?.endsWith("/")) {
|
|
59
107
|
remoteUrl = remoteUrl.slice(0, -1);
|
|
@@ -64,21 +112,23 @@ export default class WebSiteContentService
|
|
|
64
112
|
isDesign: site.isDesign,
|
|
65
113
|
eSiteID: this.ecs.general.encrypt(site.folderID.toString()),
|
|
66
114
|
remoteUrl: site.remoteUrl,
|
|
67
|
-
isTemplate: site.isTemplate
|
|
115
|
+
isTemplate: site.isTemplate,
|
|
116
|
+
hasEmailTemplates: site.hasEmailTemplates,
|
|
117
|
+
draftMode,
|
|
118
|
+
cacheKey,
|
|
119
|
+
host
|
|
68
120
|
} as ISiteFolder;
|
|
69
121
|
}
|
|
70
122
|
|
|
71
123
|
@cacheFor()
|
|
72
124
|
async getWebSiteFolder(folderID) {
|
|
73
|
-
|
|
74
|
-
return replicaReader.query((db) => db.websiteFolders.where({ folderID }, (p) => (x) => x.folderID === p.folderID)
|
|
125
|
+
return this.replicaReader.query((db) => db.websiteFolders.where({ folderID }, (p) => (x) => x.folderID === p.folderID)
|
|
75
126
|
.first());
|
|
76
127
|
}
|
|
77
128
|
|
|
78
129
|
@cacheFor()
|
|
79
130
|
async getWebSite(host) {
|
|
80
|
-
const
|
|
81
|
-
const folder = await replicaReader.query((db) => this.db.websiteFolders.where({ host }, (p) => (x) => x.hosts.some((s) => s.host === p.host))
|
|
131
|
+
const folder = await this.replicaReader.query((db) => db.websiteFolders.where({ host }, (p) => (x) => x.hosts.some((s) => s.host === p.host))
|
|
82
132
|
.first());
|
|
83
133
|
if (!folder) {
|
|
84
134
|
return null;
|
|
@@ -106,11 +156,11 @@ export default class WebSiteContentService
|
|
|
106
156
|
async getFileInfo(folderID, ... segments: string[]): Promise<IFileInfo> {
|
|
107
157
|
const [top, ... paths] = segments;
|
|
108
158
|
const eTop = top.replace(/(\%|\_)/i, (x) => "\\" + x);
|
|
109
|
-
const child = await this.db.appFiles
|
|
159
|
+
const child = await this.replicaReader.query((db) => db.appFiles
|
|
110
160
|
.where({ folderID, eTop },(p) => (x) => x.parentID === p.folderID && Sql.text.iLike(x.name, p.eTop))
|
|
111
161
|
.orderBy(void 0, (p) => (x) => x.isDeleted)
|
|
112
162
|
.thenByDescending({ top }, (p) => (x) => x.name === p.top)
|
|
113
|
-
.first();
|
|
163
|
+
.first());
|
|
114
164
|
if (!child) {
|
|
115
165
|
return null;
|
|
116
166
|
}
|
|
@@ -141,24 +191,33 @@ export default class WebSiteContentService
|
|
|
141
191
|
* @returns
|
|
142
192
|
*/
|
|
143
193
|
async getSnapshotFile(siteFolder: ISiteFolder, path: string[]) {
|
|
144
|
-
const { snapshotFolderID } = siteFolder;
|
|
145
|
-
const src = await this.getFile(snapshotFolderID, ... path);
|
|
194
|
+
const { snapshotFolderID, draftMode, folderID , cacheKey } = siteFolder;
|
|
195
|
+
const src = await this.getFile(draftMode ? folderID : snapshotFolderID, ... path);
|
|
146
196
|
if (!src) {
|
|
147
197
|
return;
|
|
148
198
|
}
|
|
149
199
|
const fileName = path.pop();
|
|
150
200
|
if (/html$/i.test(src.contentType)) {
|
|
151
201
|
const currentPath = path.join("/");
|
|
152
|
-
const filePath = join(
|
|
202
|
+
const filePath = join(cacheKey, "transformed", ... path, fileName);
|
|
153
203
|
return this.siteCache.htmlCache.getOrCreateAsync(filePath, async (dest) => {
|
|
154
204
|
const ts = ServiceProvider.resolve(this, WebContentTranspileService);
|
|
155
|
-
|
|
205
|
+
let content = await ts.transformHtml(siteFolder, src, currentPath);
|
|
206
|
+
|
|
207
|
+
if (siteFolder.hasEmailTemplates) {
|
|
208
|
+
// transform email templates..
|
|
209
|
+
const { folderID: siteID, host } = siteFolder;
|
|
210
|
+
const url = `https://${host}/${currentPath}`;
|
|
211
|
+
const es = ServiceProvider.resolve(this, HtmlForEmailService);
|
|
212
|
+
content = await es.prepareHtml({ html: content, siteID, path, url });
|
|
213
|
+
}
|
|
214
|
+
|
|
156
215
|
await dest.writeAllText(content);
|
|
157
216
|
});
|
|
158
217
|
}
|
|
159
218
|
if (/css$/i.test(src.contentType)) {
|
|
160
219
|
const currentPath = path.join("/");
|
|
161
|
-
const filePath = join(
|
|
220
|
+
const filePath = join(cacheKey, "transformed", ... path, fileName);
|
|
162
221
|
return this.siteCache.htmlCache.getOrCreateAsync(filePath, async (dest) => {
|
|
163
222
|
const ts = ServiceProvider.resolve(this, WebContentTranspileService);
|
|
164
223
|
const content = await ts.transformCss(siteFolder, src, currentPath);
|
|
@@ -28,6 +28,17 @@ export default class HtmlForEmailService {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
async prepareHtml({ html, siteID, path, url }: { html: string, url :string, siteID, path: string[] }) {
|
|
32
|
+
|
|
33
|
+
const browser = new JSDOM(html, { url});
|
|
34
|
+
await new Promise((resolve, reject) => {
|
|
35
|
+
browser.window.addEventListener("load", () => {
|
|
36
|
+
void inlineCSS(browser.window, browser.window.document).then(resolve);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
html = browser.window.document.documentElement.outerHTML;
|
|
40
|
+
return html;
|
|
41
|
+
}
|
|
31
42
|
}
|
|
32
43
|
|
|
33
44
|
async function inlineCSS(window, document){
|
|
@@ -167,7 +178,7 @@ async function inlineCSS(window, document){
|
|
|
167
178
|
|
|
168
179
|
const sheets = document.styleSheets;
|
|
169
180
|
const ret = [];
|
|
170
|
-
el.matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector
|
|
181
|
+
el.matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector
|
|
171
182
|
|| el.msMatchesSelector || el.oMatchesSelector;
|
|
172
183
|
for (const i in sheets) {
|
|
173
184
|
const sheet = sheets[i];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
2
|
+
import { Route } from "@entity-access/server-pages/dist/core/Route.js";
|
|
3
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
4
|
+
import SocialMailContext from "../../../../../../server/model/SocialMailContext.js";
|
|
5
|
+
import { Prepare } from "@entity-access/server-pages/dist/decorators/Prepare.js";
|
|
6
|
+
import ReplicaReader from "../../../../../../server/services/replica/ReplicaReader.js";
|
|
7
|
+
import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
|
|
8
|
+
import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
|
|
9
|
+
import EncryptionService from "../../../../../../server/services/encryption/EncryptionService.js";
|
|
10
|
+
import { globalEnv } from "../../../../../../common/globalEnv.js";
|
|
11
|
+
|
|
12
|
+
@Prepare.authorize
|
|
13
|
+
export default class extends Page {
|
|
14
|
+
|
|
15
|
+
@Route("siteID")
|
|
16
|
+
siteID;
|
|
17
|
+
|
|
18
|
+
@Inject
|
|
19
|
+
db: SocialMailContext;
|
|
20
|
+
|
|
21
|
+
@Inject
|
|
22
|
+
ecs: EncryptionService;
|
|
23
|
+
|
|
24
|
+
@Inject
|
|
25
|
+
replicaReader: ReplicaReader;
|
|
26
|
+
|
|
27
|
+
async run() {
|
|
28
|
+
|
|
29
|
+
const site = await this.replicaReader.query((db) => db.websiteFolders.filtered("read").where(this, (p) => (x) => x.folderID === p.siteID)
|
|
30
|
+
.first());
|
|
31
|
+
|
|
32
|
+
if(!site) {
|
|
33
|
+
throw new EntityAccessError("Site not found");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const time = site.lastModified ? DateTime.from(site.lastModified) : DateTime.now;
|
|
37
|
+
|
|
38
|
+
let path = this.childPath.join("/");
|
|
39
|
+
if(!path) {
|
|
40
|
+
path = "index.html";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const encoded = this.ecs.general.encrypt(`${site.folderID.toString(36)}-${time.msSinceEpoch.toString(36)}`, "hex");
|
|
44
|
+
const host = `${globalEnv.serverID}-${encoded}`;
|
|
45
|
+
|
|
46
|
+
return this.redirect(`https://${host}.sites.${globalEnv.wildcardDomain}/${path}`);
|
|
47
|
+
}
|
|
48
|
+
}
|