@social-mail/social-mail-web-server 1.4.882 → 1.4.883
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/content/video/all.webm +0 -0
- package/dist/server/model/entities/WebSiteFolder.d.ts +2 -0
- package/dist/server/model/entities/WebSiteFolder.d.ts.map +1 -1
- package/dist/server/model/entities/WebSiteFolder.js +8 -0
- package/dist/server/model/entities/WebSiteFolder.js.map +1 -1
- package/dist/server/services/captcha/CaptchaService.d.ts +16 -0
- package/dist/server/services/captcha/CaptchaService.d.ts.map +1 -0
- package/dist/server/services/captcha/CaptchaService.js +107 -0
- package/dist/server/services/captcha/CaptchaService.js.map +1 -0
- package/dist/server/services/captcha/IVerification.d.ts +8 -0
- package/dist/server/services/captcha/IVerification.d.ts.map +1 -0
- package/dist/server/services/captcha/IVerification.js +2 -0
- package/dist/server/services/captcha/IVerification.js.map +1 -0
- package/dist/server/services/files/WebSiteService.d.ts +1 -0
- package/dist/server/services/files/WebSiteService.d.ts.map +1 -1
- package/dist/server/services/files/WebSiteService.js +58 -35
- package/dist/server/services/files/WebSiteService.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/wwwroot/routes/api/site/contact/post.d.ts +13 -0
- package/dist/wwwroot/routes/api/site/contact/post.d.ts.map +1 -0
- package/dist/wwwroot/routes/api/site/contact/post.js +95 -0
- package/dist/wwwroot/routes/api/site/contact/post.js.map +1 -0
- package/dist/wwwroot/routes/api/users/captcha/index.d.ts +9 -0
- package/dist/wwwroot/routes/api/users/captcha/index.d.ts.map +1 -0
- package/dist/wwwroot/routes/api/users/captcha/index.js +37 -0
- package/dist/wwwroot/routes/api/users/captcha/index.js.map +1 -0
- package/dist/wwwroot/routes/api/users/captcha/post.d.ts +8 -0
- package/dist/wwwroot/routes/api/users/captcha/post.d.ts.map +1 -0
- package/dist/wwwroot/routes/api/users/captcha/post.js +23 -0
- package/dist/wwwroot/routes/api/users/captcha/post.js.map +1 -0
- package/dist/wwwroot/routes/api/users/captcha/put.d.ts +8 -0
- package/dist/wwwroot/routes/api/users/captcha/put.d.ts.map +1 -0
- package/dist/wwwroot/routes/api/users/captcha/put.js +40 -0
- package/dist/wwwroot/routes/api/users/captcha/put.js.map +1 -0
- package/package.json +1 -1
- package/src/server/model/entities/WebSiteFolder.ts +6 -0
- package/src/server/services/captcha/CaptchaService.ts +109 -0
- package/src/server/services/captcha/IVerification.ts +7 -0
- package/src/server/services/files/WebSiteService.ts +9 -0
- package/src/wwwroot/routes/api/site/contact/post.tsx +92 -0
- package/src/wwwroot/routes/api/users/captcha/index.tsx +32 -0
- package/src/wwwroot/routes/api/users/captcha/post.tsx +18 -0
- package/src/wwwroot/routes/api/users/captcha/put.tsx +32 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
2
|
+
import WebSiteService from "../../../../../server/services/files/WebSiteService.js";
|
|
3
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
4
|
+
import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
|
|
5
|
+
import EmailAddressService from "../../../../../server/services/EmailAddressService.js";
|
|
6
|
+
export default class extends Page {
|
|
7
|
+
websiteService: WebSiteService;
|
|
8
|
+
captchaService: CaptchaService;
|
|
9
|
+
db: SocialMailContext;
|
|
10
|
+
emailAddressService: EmailAddressService;
|
|
11
|
+
run(): Promise<import("@entity-access/server-pages/dist/Content.js").default>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=post.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post.d.ts","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/api/site/contact/post.tsx"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,cAAc,MAAM,wDAAwD,CAAC;AACpF,OAAO,cAAc,MAAM,0DAA0D,CAAC;AACtF,OAAO,iBAAiB,MAAM,kDAAkD,CAAC;AACjF,OAAO,mBAAmB,MAAM,uDAAuD,CAAC;AAIxF,MAAM,CAAC,OAAO,MAAO,SAAQ,IAAI;IAG7B,cAAc,EAAE,cAAc,CAAC;IAG/B,cAAc,EAAE,cAAc,CAAC;IAG/B,EAAE,EAAE,iBAAiB,CAAC;IAGtB,mBAAmB,EAAE,mBAAmB,CAAC;IAEnC,GAAG;CAmEZ"}
|
|
@@ -0,0 +1,95 @@
|
|
|
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 { Prepare } from "@entity-access/server-pages/dist/decorators/Prepare.js";
|
|
12
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
13
|
+
import WebSiteService from "../../../../../server/services/files/WebSiteService.js";
|
|
14
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
15
|
+
import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
|
|
16
|
+
import EmailAddressService from "../../../../../server/services/EmailAddressService.js";
|
|
17
|
+
import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
|
|
18
|
+
let default_1 = class extends Page {
|
|
19
|
+
async run() {
|
|
20
|
+
const model = this.body;
|
|
21
|
+
await this.captchaService.verify(model.captcha);
|
|
22
|
+
const website = await this.websiteService.getWebSiteFolder(this.request.hostName?.toLocaleLowerCase());
|
|
23
|
+
const senderID = await this.emailAddressService.getId(website.fromEmail);
|
|
24
|
+
const to = await this.emailAddressService.getId(website.supportEmail);
|
|
25
|
+
const dateCreated = DateTime.now;
|
|
26
|
+
const dateUpdated = dateCreated;
|
|
27
|
+
const dateSent = dateCreated;
|
|
28
|
+
this.db.verifyFilters = false;
|
|
29
|
+
this.db.raiseEvents = true;
|
|
30
|
+
this.db.emails.add({
|
|
31
|
+
senderID,
|
|
32
|
+
recipients: [
|
|
33
|
+
this.db.emailRecipients.add({
|
|
34
|
+
emailAddressID: to
|
|
35
|
+
})
|
|
36
|
+
],
|
|
37
|
+
dateCreated,
|
|
38
|
+
dateUpdated,
|
|
39
|
+
dateSent,
|
|
40
|
+
status: "scheduled",
|
|
41
|
+
subject: `Website Enquiry: ` + model.subject,
|
|
42
|
+
htmlBody: `<div>
|
|
43
|
+
You have received following enquiry on the website,
|
|
44
|
+
<table>
|
|
45
|
+
<tr>
|
|
46
|
+
<td>Name</td>
|
|
47
|
+
<td>${model.name}</td>
|
|
48
|
+
</tr>
|
|
49
|
+
<tr>
|
|
50
|
+
<td>Email</td>
|
|
51
|
+
<td>${model.email}</td>
|
|
52
|
+
</tr>
|
|
53
|
+
<tr>
|
|
54
|
+
<td>Phone</td>
|
|
55
|
+
<td>${model.phone}</td>
|
|
56
|
+
</tr>
|
|
57
|
+
<tr>
|
|
58
|
+
<td colspan="2">Notes</td>
|
|
59
|
+
</tr>
|
|
60
|
+
<tr>
|
|
61
|
+
<td colspan="2">
|
|
62
|
+
${model.description}
|
|
63
|
+
</td>
|
|
64
|
+
</tr>
|
|
65
|
+
</table>
|
|
66
|
+
</div>`
|
|
67
|
+
});
|
|
68
|
+
await this.db.saveChanges();
|
|
69
|
+
await this.captchaService.delete(model.captcha);
|
|
70
|
+
return this.json({
|
|
71
|
+
sent: true
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
__decorate([
|
|
76
|
+
Inject,
|
|
77
|
+
__metadata("design:type", WebSiteService)
|
|
78
|
+
], default_1.prototype, "websiteService", void 0);
|
|
79
|
+
__decorate([
|
|
80
|
+
Inject,
|
|
81
|
+
__metadata("design:type", CaptchaService)
|
|
82
|
+
], default_1.prototype, "captchaService", void 0);
|
|
83
|
+
__decorate([
|
|
84
|
+
Inject,
|
|
85
|
+
__metadata("design:type", SocialMailContext)
|
|
86
|
+
], default_1.prototype, "db", void 0);
|
|
87
|
+
__decorate([
|
|
88
|
+
Inject,
|
|
89
|
+
__metadata("design:type", EmailAddressService)
|
|
90
|
+
], default_1.prototype, "emailAddressService", void 0);
|
|
91
|
+
default_1 = __decorate([
|
|
92
|
+
Prepare.parseJsonBody
|
|
93
|
+
], default_1);
|
|
94
|
+
export default default_1;
|
|
95
|
+
//# sourceMappingURL=post.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post.js","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/api/site/contact/post.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,MAAM,MAAM,4CAA4C,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,wDAAwD,CAAC;AACjF,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,cAAc,MAAM,wDAAwD,CAAC;AACpF,OAAO,cAAc,MAAM,0DAA0D,CAAC;AACtF,OAAO,iBAAiB,MAAM,kDAAkD,CAAC;AACjF,OAAO,mBAAmB,MAAM,uDAAuD,CAAC;AACxF,OAAO,QAAQ,MAAM,qDAAqD,CAAC;AAG5D,gBAAA,KAAM,SAAQ,IAAI;IAc7B,KAAK,CAAC,GAAG;QAEL,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QAExB,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEhD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAEvG,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAEtE,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC;QACjC,MAAM,WAAW,GAAG,WAAW,CAAC;QAChC,MAAM,QAAQ,GAAG,WAAW,CAAC;QAE7B,IAAI,CAAC,EAAE,CAAC,aAAa,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,WAAW,GAAG,IAAI,CAAC;QAE3B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;YACf,QAAQ;YACR,UAAU,EAAE;gBACR,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC;oBACxB,cAAc,EAAE,EAAE;iBACrB,CAAC;aACL;YACD,WAAW;YACX,WAAW;YACX,QAAQ;YACR,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,mBAAmB,GAAG,KAAK,CAAC,OAAO;YAC5C,QAAQ,EAAE;;;;;8BAKQ,KAAK,CAAC,IAAI;;;;8BAIV,KAAK,CAAC,KAAK;;;;8BAIX,KAAK,CAAC,KAAK;;;;;;;8BAOX,KAAK,CAAC,WAAW;;;;mBAI5B;SACV,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;QAE5B,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEhD,OAAO,IAAI,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,IAAI;SACb,CAAC,CAAC;IAEP,CAAC;CACJ,CAAA;AA9EG;IADC,MAAM;8BACS,cAAc;iDAAC;AAG/B;IADC,MAAM;8BACS,cAAc;iDAAC;AAG/B;IADC,MAAM;8BACH,iBAAiB;qCAAC;AAGtB;IADC,MAAM;8BACc,mBAAmB;sDAAC;AAZ9B;IADd,OAAO,CAAC,aAAa;aAkFrB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
2
|
+
import { TempFileResult } from "@entity-access/server-pages/dist/Content.js";
|
|
3
|
+
import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
|
|
4
|
+
export default class extends Page {
|
|
5
|
+
db: SocialMailContext;
|
|
6
|
+
private captchaService;
|
|
7
|
+
run(): Promise<TempFileResult>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/api/users/captcha/index.tsx"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAE7E,OAAO,iBAAiB,MAAM,kDAAkD,CAAC;AAGjF,MAAM,CAAC,OAAO,MAAO,SAAQ,IAAI;IAG7B,EAAE,EAAE,iBAAiB,CAAC;IAGtB,OAAO,CAAC,cAAc,CAAiB;IAGjC,GAAG;CAcZ"}
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
/* eslint-disable no-console */
|
|
11
|
+
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
12
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
13
|
+
import { TempFileResult } from "@entity-access/server-pages/dist/Content.js";
|
|
14
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
15
|
+
import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
|
|
16
|
+
export default class default_1 extends Page {
|
|
17
|
+
async run() {
|
|
18
|
+
const [id, accessCode] = this.childPath;
|
|
19
|
+
const { code } = await this.db.verificationTokens.statements.select({}, {
|
|
20
|
+
verificationID: id,
|
|
21
|
+
accessCode
|
|
22
|
+
});
|
|
23
|
+
const file = await this.captchaService.getVideo(code);
|
|
24
|
+
return new TempFileResult(file, {
|
|
25
|
+
contentDisposition: "attachment"
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
__decorate([
|
|
30
|
+
Inject,
|
|
31
|
+
__metadata("design:type", SocialMailContext)
|
|
32
|
+
], default_1.prototype, "db", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
Inject,
|
|
35
|
+
__metadata("design:type", CaptchaService)
|
|
36
|
+
], default_1.prototype, "captchaService", void 0);
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/api/users/captcha/index.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,+BAA+B;AAC/B,OAAO,MAAM,MAAM,4CAA4C,CAAC;AAChE,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAC7E,OAAO,cAAc,MAAM,0DAA0D,CAAC;AACtF,OAAO,iBAAiB,MAAM,kDAAkD,CAAC;AAGjF,MAAM,CAAC,OAAO,gBAAO,SAAQ,IAAI;IAS7B,KAAK,CAAC,GAAG;QAEL,MAAM,CAAE,EAAE,EAAE,UAAU,CAAE,GAAG,IAAI,CAAC,SAAkB,CAAC;QAEnD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE;YACpE,cAAc,EAAE,EAAE;YAClB,UAAU;SACb,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtD,OAAO,IAAI,cAAc,CAAC,IAAI,EAAE;YAC5B,kBAAkB,EAAE,YAAY;SACnC,CAAC,CAAC;IACP,CAAC;CACJ;AApBG;IADC,MAAM;8BACH,iBAAiB;qCAAC;AAGd;IADP,MAAM;8BACiB,cAAc;iDAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
2
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
3
|
+
import { IVerification } from "../../../../../server/services/captcha/IVerification.js";
|
|
4
|
+
export default class extends Page<IVerification> {
|
|
5
|
+
captchaService: CaptchaService;
|
|
6
|
+
run(): Promise<import("@entity-access/server-pages/dist/Content.js").default>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=post.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post.d.ts","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/api/users/captcha/post.tsx"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAE5D,OAAO,cAAc,MAAM,0DAA0D,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAExF,MAAM,CAAC,OAAO,MAAO,SAAQ,IAAI,CAAC,aAAa,CAAC;IAG5C,cAAc,EAAE,cAAc,CAAC;IAEzB,GAAG;CAOZ"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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 Page from "@entity-access/server-pages/dist/Page.js";
|
|
11
|
+
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
12
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
13
|
+
export default class default_1 extends Page {
|
|
14
|
+
async run() {
|
|
15
|
+
this.captchaService.verify(this.body);
|
|
16
|
+
return this.json(this.body);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
__decorate([
|
|
20
|
+
Inject,
|
|
21
|
+
__metadata("design:type", CaptchaService)
|
|
22
|
+
], default_1.prototype, "captchaService", void 0);
|
|
23
|
+
//# sourceMappingURL=post.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post.js","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/api/users/captcha/post.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,MAAM,MAAM,4CAA4C,CAAC;AAChE,OAAO,cAAc,MAAM,0DAA0D,CAAC;AAGtF,MAAM,CAAC,OAAO,gBAAO,SAAQ,IAAmB;IAK5C,KAAK,CAAC,GAAG;QAEL,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEhC,CAAC;CAEJ;AATG;IADC,MAAM;8BACS,cAAc;iDAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
2
|
+
import Content from "@entity-access/server-pages/dist/Content.js";
|
|
3
|
+
export default class extends Page {
|
|
4
|
+
private captchaService;
|
|
5
|
+
private rateLimiterService;
|
|
6
|
+
run(): Promise<Content>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=put.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"put.d.ts","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/api/users/captcha/put.tsx"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,OAAO,MAAM,6CAA6C,CAAC;AAIlE,MAAM,CAAC,OAAO,MAAO,SAAQ,IAAI;IAG7B,OAAO,CAAC,cAAc,CAAiB;IAGvC,OAAO,CAAC,kBAAkB,CAAqB;IAEzC,GAAG;CAiBZ"}
|
|
@@ -0,0 +1,40 @@
|
|
|
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 Page from "@entity-access/server-pages/dist/Page.js";
|
|
12
|
+
import Content from "@entity-access/server-pages/dist/Content.js";
|
|
13
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
14
|
+
import RateLimiterService from "../../../../../server/services/rate-limiter/RateLimiterService.js";
|
|
15
|
+
export default class default_1 extends Page {
|
|
16
|
+
async run() {
|
|
17
|
+
const ip = this.request?.remoteIPAddress ?? "";
|
|
18
|
+
const rl = await this.rateLimiterService.acquire(ip, "captcha");
|
|
19
|
+
if (!rl) {
|
|
20
|
+
return Content.create({
|
|
21
|
+
body: "Rate Limited",
|
|
22
|
+
status: 429
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const { id, accessCode } = await this.captchaService.generatePair(ip);
|
|
26
|
+
return this.json({
|
|
27
|
+
id,
|
|
28
|
+
accessCode
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
__decorate([
|
|
33
|
+
Inject,
|
|
34
|
+
__metadata("design:type", CaptchaService)
|
|
35
|
+
], default_1.prototype, "captchaService", void 0);
|
|
36
|
+
__decorate([
|
|
37
|
+
Inject,
|
|
38
|
+
__metadata("design:type", RateLimiterService)
|
|
39
|
+
], default_1.prototype, "rateLimiterService", void 0);
|
|
40
|
+
//# sourceMappingURL=put.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"put.js","sourceRoot":"","sources":["../../../../../../src/wwwroot/routes/api/users/captcha/put.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,MAAM,MAAM,4CAA4C,CAAC;AAChE,OAAO,IAAI,MAAM,0CAA0C,CAAC;AAC5D,OAAO,OAAO,MAAM,6CAA6C,CAAC;AAClE,OAAO,cAAc,MAAM,0DAA0D,CAAC;AACtF,OAAO,kBAAkB,MAAM,mEAAmE,CAAC;AAEnG,MAAM,CAAC,OAAO,gBAAO,SAAQ,IAAI;IAQ7B,KAAK,CAAC,GAAG;QAEL,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,IAAI,EAAE,CAAC;QAC/C,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAChE,IAAI,CAAC,EAAE,EAAE,CAAC;YACN,OAAO,OAAO,CAAC,MAAM,CAAC;gBAClB,IAAI,EAAE,cAAc;gBACpB,MAAM,EAAE,GAAG;aACd,CAAC,CAAC;QACP,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC,IAAI,CAAC;YACb,EAAE;YACF,UAAU;SACb,CAAC,CAAC;IACP,CAAC;CACJ;AAtBW;IADP,MAAM;8BACiB,cAAc;iDAAC;AAG/B;IADP,MAAM;8BACqB,kBAAkB;qDAAC"}
|
package/package.json
CHANGED
|
@@ -49,6 +49,12 @@ export default class WebSiteFolder {
|
|
|
49
49
|
@Column({ dataType:"BigInt", default: () => 0})
|
|
50
50
|
public snapshotStorage: number;
|
|
51
51
|
|
|
52
|
+
@Column({ dataType:"Char", length: 200, nullable: true})
|
|
53
|
+
public supportEmail: string;
|
|
54
|
+
|
|
55
|
+
@Column({ dataType:"Char", length: 200, nullable: true})
|
|
56
|
+
public fromEmail: string;
|
|
57
|
+
|
|
52
58
|
public folder: AppFile;
|
|
53
59
|
|
|
54
60
|
currentVersion: AppFile;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import Inject, { RegisterScoped } from "@entity-access/entity-access/dist/di/di.js";
|
|
2
|
+
import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
|
|
3
|
+
import EntityAccessError from "@entity-access/entity-access/dist/common/EntityAccessError.js";
|
|
4
|
+
import ensureDir from "../../../common/FileApi.js";
|
|
5
|
+
import { spawnPromise } from "../../../common/spawnPromise.js";
|
|
6
|
+
import TempFileService from "../../storage/TempFileService.js";
|
|
7
|
+
import DiskCacheService from "../cache/DiskCacheService.js";
|
|
8
|
+
import EncryptionService from "../encryption/EncryptionService.js";
|
|
9
|
+
import { IVerification } from "./IVerification.js";
|
|
10
|
+
import SocialMailContext from "../../model/SocialMailContext.js";
|
|
11
|
+
import { randomUUID } from "crypto";
|
|
12
|
+
|
|
13
|
+
const captchaCache = "/cache/captcha";
|
|
14
|
+
|
|
15
|
+
ensureDir(captchaCache);
|
|
16
|
+
|
|
17
|
+
const zero = '0'.charCodeAt(0);
|
|
18
|
+
|
|
19
|
+
const filter = "[0]pad=width=750:height=200:x=0:y=0:color=white[v0];"
|
|
20
|
+
+ "[0][1]hstack=inputs=2[i1];"
|
|
21
|
+
+ "[i1]pad=width=750:height=200:x=0:y=0:color=white[v1];"
|
|
22
|
+
+ "[0][1][2]hstack=inputs=3[i2];"
|
|
23
|
+
+ "[i2]pad=width=750:height=200:x=0:y=0:color=white[v2];"
|
|
24
|
+
+ "[0][1][2][3]hstack=inputs=4[i3];"
|
|
25
|
+
+ "[i3]pad=width=750:height=200:x=0:y=0:color=white[v3];"
|
|
26
|
+
+ "[0][1][2][3][4]hstack=inputs=5[i4];"
|
|
27
|
+
+ "[i4]pad=width=750:height=200:x=0:y=0:color=white[v4];"
|
|
28
|
+
+ "[v0][v1][v2][v3][v4]concat=n=5:v=1,format=yuv420p[v]";
|
|
29
|
+
|
|
30
|
+
@RegisterScoped
|
|
31
|
+
export default class CaptchaService {
|
|
32
|
+
|
|
33
|
+
@Inject
|
|
34
|
+
private diskCache: DiskCacheService;
|
|
35
|
+
|
|
36
|
+
@Inject
|
|
37
|
+
private encryption: EncryptionService;
|
|
38
|
+
|
|
39
|
+
@Inject
|
|
40
|
+
private db: SocialMailContext;
|
|
41
|
+
|
|
42
|
+
@Inject
|
|
43
|
+
private tfs: TempFileService;
|
|
44
|
+
|
|
45
|
+
async verify(v: IVerification) {
|
|
46
|
+
const { id, accessCode, code } = v;
|
|
47
|
+
const vt = await this.db.verificationTokens.statements.select({}, { verificationID: id as any, accessCode, code });
|
|
48
|
+
if (!vt) {
|
|
49
|
+
throw new EntityAccessError(`Invalid code`);
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async delete(v: IVerification) {
|
|
55
|
+
const { id, accessCode, code } = v;
|
|
56
|
+
await this.db.verificationTokens.statements.delete({ verificationID: id as any, accessCode, code });
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async generatePair(ip = "") {
|
|
61
|
+
|
|
62
|
+
const { db } = this;
|
|
63
|
+
let code = DateTime.now.msSinceEpoch.toString();
|
|
64
|
+
code = code.substring(code.length-5);
|
|
65
|
+
|
|
66
|
+
const accessCode = randomUUID();
|
|
67
|
+
const expiry = DateTime.now.addMinutes(15);
|
|
68
|
+
|
|
69
|
+
const v = await db.verificationTokens.statements.insert({
|
|
70
|
+
code,
|
|
71
|
+
accessCode,
|
|
72
|
+
expiry
|
|
73
|
+
});
|
|
74
|
+
return { id: v.verificationID, accessCode };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async getVideo(code: string) {
|
|
78
|
+
return this.diskCache.getOrCreate("captcha/" + code + ".gif", (filePath) => this.prepareVideo(code, filePath));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async prepareVideo(code: string, saveAs: string) {
|
|
82
|
+
|
|
83
|
+
const tf = await this.tfs.createTempFile(".webm", "code", "video/webm");
|
|
84
|
+
|
|
85
|
+
const input = "/app/content/video/all.webm";
|
|
86
|
+
|
|
87
|
+
await spawnPromise("/ffmpeg/ffmpeg", [
|
|
88
|
+
"-ss", ((code.charCodeAt(0) - zero) * 3.5).toString(), "-t", "3.5", "-i", input,
|
|
89
|
+
"-ss", ((code.charCodeAt(1) - zero) * 3.5).toString(), "-t", "3.5", "-i", input,
|
|
90
|
+
"-ss", ((code.charCodeAt(2) - zero) * 3.5).toString(), "-t", "3.5", "-i", input,
|
|
91
|
+
"-ss", ((code.charCodeAt(3) - zero) * 3.5).toString(), "-t", "3.5", "-i", input,
|
|
92
|
+
"-ss", ((code.charCodeAt(4) - zero) * 3.5).toString(), "-t", "3.5", "-i", input,
|
|
93
|
+
"-filter_complex", filter,
|
|
94
|
+
"-map", "[v]",
|
|
95
|
+
"-y", tf.path
|
|
96
|
+
], {
|
|
97
|
+
logData: false
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await spawnPromise("/ffmpeg/ffmpeg", [
|
|
101
|
+
"-i", tf.path,
|
|
102
|
+
"-filter:v", "scale=300:-1",
|
|
103
|
+
"-y", saveAs
|
|
104
|
+
],{
|
|
105
|
+
logData: false
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
}
|
|
@@ -28,6 +28,15 @@ export default class WebSiteService {
|
|
|
28
28
|
return folder;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
@cacheFor()
|
|
32
|
+
async getWebSiteFolder(host: string) {
|
|
33
|
+
using scope = globalServices.createScope();
|
|
34
|
+
const db = scope.resolve(SocialMailContext);
|
|
35
|
+
const folder = await db.websiteFolders.where({ host }, (p) => (x) => x.hosts.some((s) => s.host === p.host))
|
|
36
|
+
.first();
|
|
37
|
+
return folder;
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
async getCurrentSnapshotFolder(host: string) {
|
|
32
41
|
using scope = globalServices.createScope();
|
|
33
42
|
const db = scope.resolve(SocialMailContext);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
2
|
+
import { Prepare } from "@entity-access/server-pages/dist/decorators/Prepare.js";
|
|
3
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
4
|
+
import WebSiteService from "../../../../../server/services/files/WebSiteService.js";
|
|
5
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
6
|
+
import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
|
|
7
|
+
import EmailAddressService from "../../../../../server/services/EmailAddressService.js";
|
|
8
|
+
import DateTime from "@entity-access/entity-access/dist/types/DateTime.js";
|
|
9
|
+
|
|
10
|
+
@Prepare.parseJsonBody
|
|
11
|
+
export default class extends Page {
|
|
12
|
+
|
|
13
|
+
@Inject
|
|
14
|
+
websiteService: WebSiteService;
|
|
15
|
+
|
|
16
|
+
@Inject
|
|
17
|
+
captchaService: CaptchaService;
|
|
18
|
+
|
|
19
|
+
@Inject
|
|
20
|
+
db: SocialMailContext;
|
|
21
|
+
|
|
22
|
+
@Inject
|
|
23
|
+
emailAddressService: EmailAddressService;
|
|
24
|
+
|
|
25
|
+
async run() {
|
|
26
|
+
|
|
27
|
+
const model = this.body;
|
|
28
|
+
|
|
29
|
+
await this.captchaService.verify(model.captcha);
|
|
30
|
+
|
|
31
|
+
const website = await this.websiteService.getWebSiteFolder(this.request.hostName?.toLocaleLowerCase());
|
|
32
|
+
|
|
33
|
+
const senderID = await this.emailAddressService.getId(website.fromEmail);
|
|
34
|
+
|
|
35
|
+
const to = await this.emailAddressService.getId(website.supportEmail);
|
|
36
|
+
|
|
37
|
+
const dateCreated = DateTime.now;
|
|
38
|
+
const dateUpdated = dateCreated;
|
|
39
|
+
const dateSent = dateCreated;
|
|
40
|
+
|
|
41
|
+
this.db.verifyFilters = false;
|
|
42
|
+
this.db.raiseEvents = true;
|
|
43
|
+
|
|
44
|
+
this.db.emails.add({
|
|
45
|
+
senderID,
|
|
46
|
+
recipients: [
|
|
47
|
+
this.db.emailRecipients.add({
|
|
48
|
+
emailAddressID: to
|
|
49
|
+
})
|
|
50
|
+
],
|
|
51
|
+
dateCreated,
|
|
52
|
+
dateUpdated,
|
|
53
|
+
dateSent,
|
|
54
|
+
status: "scheduled",
|
|
55
|
+
subject: `Website Enquiry: ` + model.subject,
|
|
56
|
+
htmlBody: `<div>
|
|
57
|
+
You have received following enquiry on the website,
|
|
58
|
+
<table>
|
|
59
|
+
<tr>
|
|
60
|
+
<td>Name</td>
|
|
61
|
+
<td>${model.name}</td>
|
|
62
|
+
</tr>
|
|
63
|
+
<tr>
|
|
64
|
+
<td>Email</td>
|
|
65
|
+
<td>${model.email}</td>
|
|
66
|
+
</tr>
|
|
67
|
+
<tr>
|
|
68
|
+
<td>Phone</td>
|
|
69
|
+
<td>${model.phone}</td>
|
|
70
|
+
</tr>
|
|
71
|
+
<tr>
|
|
72
|
+
<td colspan="2">Notes</td>
|
|
73
|
+
</tr>
|
|
74
|
+
<tr>
|
|
75
|
+
<td colspan="2">
|
|
76
|
+
${model.description}
|
|
77
|
+
</td>
|
|
78
|
+
</tr>
|
|
79
|
+
</table>
|
|
80
|
+
</div>`
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
await this.db.saveChanges();
|
|
84
|
+
|
|
85
|
+
await this.captchaService.delete(model.captcha);
|
|
86
|
+
|
|
87
|
+
return this.json({
|
|
88
|
+
sent: true
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
3
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
4
|
+
import { TempFileResult } from "@entity-access/server-pages/dist/Content.js";
|
|
5
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
6
|
+
import SocialMailContext from "../../../../../server/model/SocialMailContext.js";
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export default class extends Page {
|
|
10
|
+
|
|
11
|
+
@Inject
|
|
12
|
+
db: SocialMailContext;
|
|
13
|
+
|
|
14
|
+
@Inject
|
|
15
|
+
private captchaService: CaptchaService;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
async run() {
|
|
19
|
+
|
|
20
|
+
const [ id, accessCode ] = this.childPath as any[];
|
|
21
|
+
|
|
22
|
+
const { code } = await this.db.verificationTokens.statements.select({}, {
|
|
23
|
+
verificationID: id,
|
|
24
|
+
accessCode
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const file = await this.captchaService.getVideo(code);
|
|
28
|
+
return new TempFileResult(file, {
|
|
29
|
+
contentDisposition: "attachment"
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
2
|
+
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
3
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
4
|
+
import { IVerification } from "../../../../../server/services/captcha/IVerification.js";
|
|
5
|
+
|
|
6
|
+
export default class extends Page<IVerification> {
|
|
7
|
+
|
|
8
|
+
@Inject
|
|
9
|
+
captchaService: CaptchaService;
|
|
10
|
+
|
|
11
|
+
async run() {
|
|
12
|
+
|
|
13
|
+
this.captchaService.verify(this.body);
|
|
14
|
+
return this.json(this.body);
|
|
15
|
+
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Inject from "@entity-access/entity-access/dist/di/di.js";
|
|
2
|
+
import Page from "@entity-access/server-pages/dist/Page.js";
|
|
3
|
+
import Content from "@entity-access/server-pages/dist/Content.js";
|
|
4
|
+
import CaptchaService from "../../../../../server/services/captcha/CaptchaService.js";
|
|
5
|
+
import RateLimiterService from "../../../../../server/services/rate-limiter/RateLimiterService.js";
|
|
6
|
+
|
|
7
|
+
export default class extends Page {
|
|
8
|
+
|
|
9
|
+
@Inject
|
|
10
|
+
private captchaService: CaptchaService;
|
|
11
|
+
|
|
12
|
+
@Inject
|
|
13
|
+
private rateLimiterService: RateLimiterService;
|
|
14
|
+
|
|
15
|
+
async run() {
|
|
16
|
+
|
|
17
|
+
const ip = this.request?.remoteIPAddress ?? "";
|
|
18
|
+
const rl = await this.rateLimiterService.acquire(ip, "captcha");
|
|
19
|
+
if (!rl) {
|
|
20
|
+
return Content.create({
|
|
21
|
+
body: "Rate Limited",
|
|
22
|
+
status: 429
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { id, accessCode } = await this.captchaService.generatePair(ip);
|
|
27
|
+
return this.json({
|
|
28
|
+
id,
|
|
29
|
+
accessCode
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|