@clairejs/server 3.15.2 → 3.16.0
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/.mocharc.json +3 -0
- package/dist/common/AbstractController.js +3 -0
- package/dist/common/ControllerMetadata.js +1 -0
- package/dist/common/FileOperation.js +6 -0
- package/dist/common/ServerModelMetadata.js +1 -0
- package/dist/common/Transactionable.js +17 -0
- package/dist/common/auth/AbstractPrincipalResolver.js +2 -0
- package/dist/common/auth/IPrincipal.js +1 -0
- package/dist/common/constants.js +7 -0
- package/dist/common/decorator.d.ts +2 -2
- package/dist/common/decorator.js +6 -0
- package/dist/common/request/EndpointMetadata.js +1 -0
- package/dist/common/request/HttpData.js +1 -0
- package/dist/common/request/HttpEndpoint.js +1 -0
- package/dist/common/request/JobData.js +1 -0
- package/dist/common/request/MountedEndpointInfo.js +1 -0
- package/dist/common/request/RequestOptions.js +1 -0
- package/dist/common/request/SocketData.js +1 -0
- package/dist/common/request/types.d.ts +1 -1
- package/dist/common/request/types.js +1 -0
- package/dist/controllers/FileManageController.js +90 -0
- package/dist/controllers/FileUploadController.js +64 -0
- package/dist/controllers/dto/system.js +14 -0
- package/dist/controllers/dto/upload.js +205 -0
- package/dist/http/auth/AbstractHttpAuthorizer.js +2 -0
- package/dist/http/common/HttpRequest.js +72 -0
- package/dist/http/common/HttpResponse.js +62 -0
- package/dist/http/controller/AbstractHttpController.js +21 -0
- package/dist/http/controller/AbstractHttpMiddleware.js +2 -0
- package/dist/http/controller/AbstractHttpRequestHandler.js +69 -0
- package/dist/http/controller/CrudHttpController.js +302 -0
- package/dist/http/controller/DefaultHttpRequestHandler.js +143 -0
- package/dist/http/decorators.d.ts +1 -1
- package/dist/http/decorators.js +86 -0
- package/dist/http/file-upload/AbstractFileUploadHandler.js +2 -0
- package/dist/http/file-upload/FileUploadHandler.js +41 -0
- package/dist/http/file-upload/types.d.ts +1 -1
- package/dist/http/file-upload/types.js +1 -0
- package/dist/http/repository/AbstractRepository.js +26 -0
- package/dist/http/repository/DtoRepository.d.ts +3 -3
- package/dist/http/repository/DtoRepository.js +204 -0
- package/dist/http/repository/ICrudRepository.js +1 -0
- package/dist/http/repository/ModelRepository.js +696 -0
- package/dist/http/security/AbstractAccessCondition.js +2 -0
- package/dist/http/security/access-conditions/FilterModelFieldAccessCondition.js +30 -0
- package/dist/http/security/access-conditions/MaximumQueryLimit.js +31 -0
- package/dist/http/security/cors.js +1 -0
- package/dist/http/utils.js +32 -0
- package/dist/index.js +75 -1
- package/dist/job/AbstractJobController.js +9 -0
- package/dist/job/AbstractJobRepository.js +2 -0
- package/dist/job/AbstractJobScheduler.js +48 -0
- package/dist/job/AwsJobScheduler.js +405 -0
- package/dist/job/LocalJobScheduler.js +273 -0
- package/dist/job/decorators.js +57 -0
- package/dist/job/interfaces.js +10 -0
- package/dist/logging/FileLogMedium.js +44 -0
- package/dist/services/AbstractFileService.js +28 -0
- package/dist/services/AbstractMailService.js +2 -0
- package/dist/services/AbstractService.js +3 -0
- package/dist/services/AbstractSmsService.js +2 -0
- package/dist/services/implementations/LocalFileService.js +42 -0
- package/dist/services/implementations/LocalMailService.js +27 -0
- package/dist/services/implementations/LocalSmsService.js +17 -0
- package/dist/services/implementations/S3FileService.js +107 -0
- package/dist/services/implementations/SesMailService.js +64 -0
- package/dist/socket/AbstractServerSocket.js +44 -0
- package/dist/socket/AbstractServerSocketManager.d.ts +1 -1
- package/dist/socket/AbstractServerSocketManager.js +348 -0
- package/dist/socket/AbstractSocketConnectionHandler.js +2 -0
- package/dist/socket/AbstractSocketController.d.ts +3 -3
- package/dist/socket/AbstractSocketController.js +12 -0
- package/dist/socket/AwsSocketManager.d.ts +2 -2
- package/dist/socket/AwsSocketManager.js +160 -0
- package/dist/socket/IServerSocket.js +1 -0
- package/dist/socket/LocalSocketManager.js +292 -0
- package/dist/system/ClaireServer.js +78 -0
- package/dist/system/ExpressWrapper.js +122 -0
- package/dist/system/LambdaWrapper.js +151 -0
- package/dist/system/ServerGlobalStore.js +1 -0
- package/dist/system/lamba-request-mapper.js +49 -0
- package/dist/system/locale/LocaleEntry.js +13 -0
- package/dist/system/locale/LocaleTranslation.js +47 -0
- package/dist/system/locale/decorators.js +14 -0
- package/package.json +13 -20
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Errors, initObjectMetadata } from "@clairejs/core";
|
|
2
|
+
export const IntervalJob = (
|
|
3
|
+
/**
|
|
4
|
+
* Unique name of job
|
|
5
|
+
*/
|
|
6
|
+
jobName,
|
|
7
|
+
/**
|
|
8
|
+
* Interval duration in second
|
|
9
|
+
*/
|
|
10
|
+
interval) => (prototype, propertyKey) => {
|
|
11
|
+
const metadata = initObjectMetadata(prototype);
|
|
12
|
+
if (!metadata.jobs) {
|
|
13
|
+
metadata.jobs = [];
|
|
14
|
+
}
|
|
15
|
+
metadata.jobs.push({
|
|
16
|
+
jobName,
|
|
17
|
+
interval,
|
|
18
|
+
handlerName: propertyKey,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
export const CronJob = (
|
|
22
|
+
/**
|
|
23
|
+
* Unique name of job
|
|
24
|
+
*/
|
|
25
|
+
jobName,
|
|
26
|
+
/**
|
|
27
|
+
* Cron expression
|
|
28
|
+
*/
|
|
29
|
+
cron) => (prototype, propertyKey) => {
|
|
30
|
+
const metadata = initObjectMetadata(prototype);
|
|
31
|
+
if (!metadata.jobs) {
|
|
32
|
+
metadata.jobs = [];
|
|
33
|
+
}
|
|
34
|
+
//-- validate cron
|
|
35
|
+
if (cron.split(" ").length !== 5) {
|
|
36
|
+
throw Errors.SYSTEM_ERROR("Invalid cron expression, expect minute / hour / day / month / day-of-week");
|
|
37
|
+
}
|
|
38
|
+
metadata.jobs.push({
|
|
39
|
+
jobName,
|
|
40
|
+
cron,
|
|
41
|
+
handlerName: propertyKey,
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
export const CustomJob = (
|
|
45
|
+
/**
|
|
46
|
+
* Unique name of job
|
|
47
|
+
*/
|
|
48
|
+
jobName) => (prototype, propertyKey) => {
|
|
49
|
+
const metadata = initObjectMetadata(prototype);
|
|
50
|
+
if (!metadata.jobs) {
|
|
51
|
+
metadata.jobs = [];
|
|
52
|
+
}
|
|
53
|
+
metadata.jobs.push({
|
|
54
|
+
jobName,
|
|
55
|
+
handlerName: propertyKey,
|
|
56
|
+
});
|
|
57
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const INTERVAL_REQUEST_METHOD = "interval";
|
|
2
|
+
export const CRON_REQUEST_METHOD = "cron";
|
|
3
|
+
export var JobInterval;
|
|
4
|
+
(function (JobInterval) {
|
|
5
|
+
JobInterval[JobInterval["EVERY_5S"] = 5] = "EVERY_5S";
|
|
6
|
+
JobInterval[JobInterval["EVERY_10S"] = 10] = "EVERY_10S";
|
|
7
|
+
JobInterval[JobInterval["EVERY_15S"] = 15] = "EVERY_15S";
|
|
8
|
+
JobInterval[JobInterval["EVERY_20S"] = 20] = "EVERY_20S";
|
|
9
|
+
JobInterval[JobInterval["EVERY_30S"] = 30] = "EVERY_30S";
|
|
10
|
+
})(JobInterval || (JobInterval = {}));
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
var FileLogMedium_1;
|
|
11
|
+
import fs from "fs";
|
|
12
|
+
import path from "path";
|
|
13
|
+
import { LogLevel, Initable } from "@clairejs/core";
|
|
14
|
+
let FileLogMedium = FileLogMedium_1 = class FileLogMedium {
|
|
15
|
+
static levels = Object.values(LogLevel);
|
|
16
|
+
destination;
|
|
17
|
+
separated;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
const paths = config.separated
|
|
20
|
+
? FileLogMedium_1.levels.map((level) => path.join(config.destination, level + ".log"))
|
|
21
|
+
: [config.destination];
|
|
22
|
+
//-- open files and let the OS close the file(s)
|
|
23
|
+
this.destination = paths.map((p) => {
|
|
24
|
+
if (!fs.existsSync(path.dirname(p))) {
|
|
25
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
return fs.openSync(p, "a");
|
|
28
|
+
});
|
|
29
|
+
this.separated = !!config.separated;
|
|
30
|
+
}
|
|
31
|
+
async init() { }
|
|
32
|
+
exit() {
|
|
33
|
+
this.destination.forEach((dest) => fs.closeSync(dest));
|
|
34
|
+
}
|
|
35
|
+
write(level, content) {
|
|
36
|
+
const fd = this.separated ? this.destination[FileLogMedium_1.levels.indexOf(level)] : 0;
|
|
37
|
+
fs.appendFileSync(fd, content);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
FileLogMedium = FileLogMedium_1 = __decorate([
|
|
41
|
+
Initable(),
|
|
42
|
+
__metadata("design:paramtypes", [Object])
|
|
43
|
+
], FileLogMedium);
|
|
44
|
+
export { FileLogMedium };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { FileOperation } from "../common/FileOperation";
|
|
2
|
+
const delay = (timeMs) => new Promise((resolve) => setTimeout(resolve, timeMs));
|
|
3
|
+
export class AbstractFileService {
|
|
4
|
+
async getUploadUrlForTempUri(temporaryUri) {
|
|
5
|
+
const getPutUrl = async () => {
|
|
6
|
+
const result = await this.getPresignedUrl(FileOperation.PUT, [temporaryUri]);
|
|
7
|
+
return result[0];
|
|
8
|
+
};
|
|
9
|
+
const getDeleteUrl = async () => {
|
|
10
|
+
const result = await this.getPresignedUrl(FileOperation.DELETE, [temporaryUri]);
|
|
11
|
+
return result[0];
|
|
12
|
+
};
|
|
13
|
+
let result = {
|
|
14
|
+
objectKey: temporaryUri,
|
|
15
|
+
putPresignedUrl: await getPutUrl(),
|
|
16
|
+
deletePresignedUrl: await getDeleteUrl(),
|
|
17
|
+
};
|
|
18
|
+
while (result.putPresignedUrl.endsWith("/")) {
|
|
19
|
+
await delay(1000);
|
|
20
|
+
result.putPresignedUrl = await getPutUrl();
|
|
21
|
+
}
|
|
22
|
+
while (result.deletePresignedUrl.endsWith("/")) {
|
|
23
|
+
await delay(1000);
|
|
24
|
+
result.deletePresignedUrl = await getDeleteUrl();
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { FileOperation } from "../../common/FileOperation";
|
|
3
|
+
import { AbstractFileService } from "../AbstractFileService";
|
|
4
|
+
export class LocalFileService extends AbstractFileService {
|
|
5
|
+
fileServerUrl;
|
|
6
|
+
constructor(fileServerUrl) {
|
|
7
|
+
super();
|
|
8
|
+
this.fileServerUrl = fileServerUrl;
|
|
9
|
+
}
|
|
10
|
+
async getFileSize(objectKeys) {
|
|
11
|
+
const fileInfo = Promise.all(objectKeys.map(async (uri) => {
|
|
12
|
+
const response = await axios.head(`${this.fileServerUrl}/info?objectKey="/${uri}"`);
|
|
13
|
+
return response.data?.size || 0;
|
|
14
|
+
}));
|
|
15
|
+
return fileInfo;
|
|
16
|
+
}
|
|
17
|
+
async getAccessUrls(uris, _isPublic) {
|
|
18
|
+
return uris.map((key) => `${this.fileServerUrl}/${key}`);
|
|
19
|
+
}
|
|
20
|
+
async getPresignedUrl(operation, uris) {
|
|
21
|
+
if (operation === FileOperation.GET) {
|
|
22
|
+
return this.getAccessUrls(uris, true);
|
|
23
|
+
}
|
|
24
|
+
return uris.map((uri) => `${this.fileServerUrl}/?objectKey="/${uri}"`);
|
|
25
|
+
}
|
|
26
|
+
async moveObject(uris) {
|
|
27
|
+
await Promise.all(uris.map((uri) => axios.post(`${this.fileServerUrl}/`, {
|
|
28
|
+
from: uri.fromURI,
|
|
29
|
+
to: uri.toURI,
|
|
30
|
+
})));
|
|
31
|
+
}
|
|
32
|
+
async copyObject(uris) {
|
|
33
|
+
await Promise.all(uris.map((uri) => axios.post(`${this.fileServerUrl}/`, {
|
|
34
|
+
from: uri.fromURI,
|
|
35
|
+
to: uri.toURI,
|
|
36
|
+
copy: true,
|
|
37
|
+
})));
|
|
38
|
+
}
|
|
39
|
+
async removeObject(uris) {
|
|
40
|
+
await Promise.all(uris.map((uri) => axios.delete(`${this.fileServerUrl}/?objectKey="/${uri}"`)));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { AbstractMailService } from "../AbstractMailService";
|
|
4
|
+
export class LocalMailService extends AbstractMailService {
|
|
5
|
+
folderPath;
|
|
6
|
+
constructor(folderPath) {
|
|
7
|
+
super();
|
|
8
|
+
this.folderPath = folderPath;
|
|
9
|
+
if (!fs.existsSync(this.folderPath)) {
|
|
10
|
+
fs.mkdirSync(folderPath, { recursive: true });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async send(email) {
|
|
14
|
+
//-- write email to local folder
|
|
15
|
+
const mailFilePath = path.join(this.folderPath, `${Date.now()}.html`);
|
|
16
|
+
fs.writeFileSync(mailFilePath, `
|
|
17
|
+
From: ${email.sender}\n
|
|
18
|
+
To: ${email.receivers.join(", ")}\n
|
|
19
|
+
Cc: ${(email.cc || []).join(", ")}\n
|
|
20
|
+
Bcc: ${(email.bcc || []).join(", ")}\n
|
|
21
|
+
|
|
22
|
+
Subject: ${email.subject}\n
|
|
23
|
+
Content: ${email.contentType}\n
|
|
24
|
+
${email.content}
|
|
25
|
+
`.trim());
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { AbstractSmsService } from "../AbstractSmsService";
|
|
4
|
+
export class LocalSmsService extends AbstractSmsService {
|
|
5
|
+
folderPath;
|
|
6
|
+
constructor(folderPath) {
|
|
7
|
+
super();
|
|
8
|
+
this.folderPath = folderPath;
|
|
9
|
+
if (!fs.existsSync(this.folderPath)) {
|
|
10
|
+
fs.mkdirSync(this.folderPath, { recursive: true });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async send(fromNumber, toNumber, content) {
|
|
14
|
+
const filePath = path.join(this.folderPath, `${Date.now()}`);
|
|
15
|
+
fs.writeFileSync(filePath, `${fromNumber}-${toNumber}: ${content}\n`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
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 { AbstractLogger, LogContext } from "@clairejs/core";
|
|
11
|
+
import aws from "aws-sdk";
|
|
12
|
+
import { AbstractFileService } from "../AbstractFileService";
|
|
13
|
+
let S3FileService = class S3FileService extends AbstractFileService {
|
|
14
|
+
config;
|
|
15
|
+
logger;
|
|
16
|
+
s3Client;
|
|
17
|
+
cloudfrontSigner;
|
|
18
|
+
constructor(config, logger) {
|
|
19
|
+
super();
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.logger = logger;
|
|
22
|
+
this.s3Client = new aws.S3({
|
|
23
|
+
signatureVersion: "v4",
|
|
24
|
+
region: this.config.S3_BUCKET_REGION,
|
|
25
|
+
});
|
|
26
|
+
this.cloudfrontSigner = new aws.CloudFront.Signer(this.config.CLOUD_FRONT_PUBLIC_KEY_ID, Buffer.from(this.config.CLOUD_FRONT_PRIVATE_KEY_BASE64, "base64").toString());
|
|
27
|
+
}
|
|
28
|
+
async getFileSize(objectKeys) {
|
|
29
|
+
return await Promise.all(objectKeys.map((uri) => this.getSingleFileSize(uri)));
|
|
30
|
+
}
|
|
31
|
+
async getAccessUrls(uris, isPublic) {
|
|
32
|
+
return uris.map((uri) => this.getSingleAccessUrl(uri, isPublic));
|
|
33
|
+
}
|
|
34
|
+
async getPresignedUrl(operation, uris) {
|
|
35
|
+
return uris.map((uri) => this.getSinglePresignedUrl(operation, uri));
|
|
36
|
+
}
|
|
37
|
+
async moveObject(uris) {
|
|
38
|
+
await Promise.all(uris.map((uri) => this.moveSingleObject(uri.fromURI, uri.toURI)));
|
|
39
|
+
}
|
|
40
|
+
async copyObject(uris) {
|
|
41
|
+
await Promise.all(uris.map((uri) => this.copySingleObject(uri.fromURI, uri.toURI)));
|
|
42
|
+
}
|
|
43
|
+
async removeObject(uris) {
|
|
44
|
+
await Promise.all(uris.map((uri) => this.removeSingleObject(uri)));
|
|
45
|
+
}
|
|
46
|
+
async getSingleFileSize(objectKey) {
|
|
47
|
+
const size = await this.s3Client
|
|
48
|
+
.headObject({ Key: objectKey, Bucket: this.config.S3_BUCKET_NAME })
|
|
49
|
+
.promise()
|
|
50
|
+
.then((res) => res.ContentLength);
|
|
51
|
+
return size || 0;
|
|
52
|
+
}
|
|
53
|
+
getSinglePresignedUrl(_operation, objectKey) {
|
|
54
|
+
return this.cloudfrontSigner.getSignedUrl({
|
|
55
|
+
url: `${this.config.CLOUD_FRONT_PUBLIC_DOMAIN}/${objectKey}`,
|
|
56
|
+
expires: Date.now() + 3600000,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async copySingleObject(fromObjectKey, toObjectKey) {
|
|
60
|
+
try {
|
|
61
|
+
await this.s3Client
|
|
62
|
+
.copyObject({
|
|
63
|
+
Bucket: this.config.S3_BUCKET_NAME,
|
|
64
|
+
CopySource: `/${this.config.S3_BUCKET_NAME}/${fromObjectKey}`,
|
|
65
|
+
Key: toObjectKey,
|
|
66
|
+
})
|
|
67
|
+
.promise();
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
this.logger.error(err);
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async moveSingleObject(fromObjectKey, toObjectKey) {
|
|
75
|
+
try {
|
|
76
|
+
await this.copySingleObject(fromObjectKey, toObjectKey);
|
|
77
|
+
await this.removeSingleObject(fromObjectKey);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
this.logger.error(err);
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
getSingleAccessUrl(objectKey, isPublic) {
|
|
85
|
+
const url = `${this.config.CLOUD_FRONT_PUBLIC_DOMAIN}/${objectKey}`;
|
|
86
|
+
if (isPublic) {
|
|
87
|
+
return url;
|
|
88
|
+
}
|
|
89
|
+
return this.cloudfrontSigner.getSignedUrl({
|
|
90
|
+
url,
|
|
91
|
+
expires: Date.now() + this.config.PRESIGNED_URL_EXPIRATION_S * 1000,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async removeSingleObject(objectKey) {
|
|
95
|
+
await this.s3Client
|
|
96
|
+
.deleteObject({
|
|
97
|
+
Bucket: this.config.S3_BUCKET_NAME,
|
|
98
|
+
Key: objectKey,
|
|
99
|
+
})
|
|
100
|
+
.promise();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
S3FileService = __decorate([
|
|
104
|
+
LogContext(),
|
|
105
|
+
__metadata("design:paramtypes", [Object, AbstractLogger])
|
|
106
|
+
], S3FileService);
|
|
107
|
+
export { S3FileService };
|
|
@@ -0,0 +1,64 @@
|
|
|
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 { AbstractLogger, Errors, LogContext } from "@clairejs/core";
|
|
11
|
+
import aws from "aws-sdk";
|
|
12
|
+
import { AbstractMailService } from "../AbstractMailService";
|
|
13
|
+
let SesMailService = class SesMailService extends AbstractMailService {
|
|
14
|
+
config;
|
|
15
|
+
logger;
|
|
16
|
+
emailClient;
|
|
17
|
+
constructor(config, logger) {
|
|
18
|
+
super();
|
|
19
|
+
this.config = config;
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
this.emailClient = new aws.SES({ apiVersion: "2010-12-01", region: this.config.SES_REGION });
|
|
22
|
+
}
|
|
23
|
+
async send(email) {
|
|
24
|
+
try {
|
|
25
|
+
const param = {
|
|
26
|
+
Destination: {
|
|
27
|
+
BccAddresses: email.bcc,
|
|
28
|
+
CcAddresses: email.cc,
|
|
29
|
+
ToAddresses: email.receivers,
|
|
30
|
+
},
|
|
31
|
+
Message: {
|
|
32
|
+
Body: {},
|
|
33
|
+
Subject: {
|
|
34
|
+
Charset: "UTF-8",
|
|
35
|
+
Data: email.subject,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
Source: email.sender,
|
|
39
|
+
};
|
|
40
|
+
if (email.contentType === "html") {
|
|
41
|
+
param.Message.Body.Html = {
|
|
42
|
+
Charset: "UTF-8",
|
|
43
|
+
Data: email.content,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
else if (email.contentType === "text") {
|
|
47
|
+
param.Message.Body.Text = {
|
|
48
|
+
Charset: "UTF-8",
|
|
49
|
+
Data: email.content,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
await this.emailClient.sendEmail(param).promise();
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
this.logger.error(err);
|
|
56
|
+
throw Errors.SYSTEM_ERROR("Cannot send email");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
SesMailService = __decorate([
|
|
61
|
+
LogContext(),
|
|
62
|
+
__metadata("design:paramtypes", [Object, AbstractLogger])
|
|
63
|
+
], SesMailService);
|
|
64
|
+
export { SesMailService };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { MessageType } from "@clairejs/core";
|
|
2
|
+
export class AbstractServerSocket {
|
|
3
|
+
socketInfo;
|
|
4
|
+
constructor(socketInfo) {
|
|
5
|
+
this.socketInfo = socketInfo;
|
|
6
|
+
}
|
|
7
|
+
getId() {
|
|
8
|
+
return this.socketInfo.id;
|
|
9
|
+
}
|
|
10
|
+
getAuthInfo() {
|
|
11
|
+
return this.socketInfo.authInfo;
|
|
12
|
+
}
|
|
13
|
+
async send(data, channel) {
|
|
14
|
+
if (channel) {
|
|
15
|
+
//-- check if socket is allowed to receive data from channel
|
|
16
|
+
if (this.socketInfo.channels.find((c) => c.name === channel && c.serverToClientAllowed)) {
|
|
17
|
+
await this.sendRaw({
|
|
18
|
+
type: MessageType.PLAIN,
|
|
19
|
+
data: { message: data, channel },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
await this.sendRaw({
|
|
25
|
+
type: MessageType.PLAIN,
|
|
26
|
+
data: {
|
|
27
|
+
message: data,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async sendRaw(data) {
|
|
33
|
+
await this.physicSend(data);
|
|
34
|
+
}
|
|
35
|
+
removeChannels(channels) {
|
|
36
|
+
this.socketInfo.channels = this.socketInfo.channels.filter((c) => !channels.includes(c.name));
|
|
37
|
+
}
|
|
38
|
+
addChannels(channelInfos) {
|
|
39
|
+
this.socketInfo.channels.push(...channelInfos);
|
|
40
|
+
}
|
|
41
|
+
getChannelsInfo() {
|
|
42
|
+
return this.socketInfo.channels;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -39,7 +39,7 @@ export declare abstract class AbstractServerSocketManager {
|
|
|
39
39
|
removeSocketFromChannel(socketId: string, channels: string[], persist?: boolean): Promise<void>;
|
|
40
40
|
abstract getSocketsByChannel(channel: string): Promise<IServerSocket[]>;
|
|
41
41
|
abstract broadcastToChannel(channel: string, data: any): Promise<void>;
|
|
42
|
-
removeSocket(socketId: string,
|
|
42
|
+
removeSocket(socketId: string, _physicRemove?: boolean): Promise<void>;
|
|
43
43
|
abstract getById(socketId: string): Promise<AbstractServerSocket | undefined>;
|
|
44
44
|
handle(socketData: SocketData): Promise<void>;
|
|
45
45
|
getMountedEndpointInfo(): Promise<MountedEndpointInfo[]>;
|