Skip to content

Commit

Permalink
Merge pull request #23 from tuana9a/big-refactor
Browse files Browse the repository at this point in the history
refactor: simplify system
  • Loading branch information
tuana9a authored Aug 9, 2024
2 parents 81b634e + 0e5b746 commit 773e7b6
Show file tree
Hide file tree
Showing 57 changed files with 239 additions and 6,507 deletions.
60 changes: 0 additions & 60 deletions .github/workflows/build-and-push-taskmanager.yaml

This file was deleted.

46 changes: 0 additions & 46 deletions .github/workflows/test-build-taskmanager.yaml

This file was deleted.

10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ mặc dù tên project là đăng ký học phần tự động tuy nhiên proje
project được triển khai dưới dạng nhiều module, được triển khai độc lập

- `web`: web frontend
- `api-gateway`: api server xử lý các request từ trình duyệt
- `api-gateway`: api server xử lý các request từ trình duyệt và xử lý kết quả mà worker trả về thông qua message queue để có các logic xử lý như tự động thử đăng ký lại
- `scheduler`: bộ hẹn giờ liên tục kiểm tra xem đã tới thời điểm hẹn giờ của sinh viên hay chưa, nếu đã đến giờ sẽ gửi yêu cầu này cho worker thông qua message queue
- `worker`: thực thi các yêu cầu đăng ký tự động, sau khi xử lý xong sẽ gửi kết quả vào message queue cho taskamager xử lý
- `taskmanager`: xử lý kết quả mà worker trả về để có các logic xử lý như tự động thử đăng ký lại
- ~~`taskmanager`: xử lý kết quả mà worker trả về để có các logic xử lý như tự động thử đăng ký lại~~ -> ĐÃ BỊ LƯỢC BỎ và THAY THẾ BỞI api-gateway
- (_**optional**_) `thoi-khoa-bieu-parser`: xử lý file excel thời khóa biểu dự kiến của nhà trường để trích xuất thông tin
- (_**optional**_) `rabbitmq`: message cho job, kết quả xử lý, ...
- (_**optional**_) `mongodb`: database
- (*) `rabbitmq`: message cho job, kết quả xử lý, ...
- (*) `mongodb`: database

các module trên sẽ truy cập, trao đổi thông tin thông qua database là [MongoDB](https://www.mongodb.com/docs/v5.0/tutorial/getting-started/) và message queue là [RabbitMQ](https://www.rabbitmq.com/getstarted.html)
các module trên sẽ truy cập, trao đổi thông tin thông qua database là [MongoDB](https://www.mongodb.com/docs/v5.0/tutorial/getting-started/) và message queue là [RabbitMQ](https://www.rabbitmq.com/getstarted.html). Với rabbitmq và mongodb các bạn có thể deploy ở chỗ khác và cập nhật connection string tương ứng trong các thành phần.

chi tiết từng module các bạn hãy click vào module tương ứng

Expand Down
2 changes: 1 addition & 1 deletion api-gateway/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 36 additions & 2 deletions api-gateway/src/cfg.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import crypto from "crypto";
import * as dotenv from "dotenv";
import { random } from "./utils";

dotenv.config();

Expand All @@ -14,6 +15,9 @@ export const cfg = {
MONGODB_CONNECTION_STRING: process.env.MONGODB_CONNECTION_STRING || "mongodb://localhost:27017",
DATABASE_NAME: process.env.DATABASE_NAME || "dkhptd",
INIT_ROOT_PASSWORD: process.env.INIT_ROOT_PASSWORD || crypto.randomBytes(32).toString("hex"),
JOB_MAX_TRY: 10,
LOG_WORKER_DOING: parseInt(process.env.LOG_WORKER_DOING),
LOG_WORKER_PING: parseInt(process.env.LOG_WORKER_PING),
};

export const JobStatus = {
Expand All @@ -22,8 +26,12 @@ export const JobStatus = {
CANCELED: 20,
DONE: 21,
FAILED: 22,
TIMEOUT_OR_STALE: 23,
UNKOWN_ERROR: 30,
MAX_RETRY_REACH: 24,
};


export const Role = {
ADMIN: "ADMIN",
};
Expand All @@ -44,7 +52,13 @@ export const CollectionName = {

export const QueueName = {
PARSE_TKB_XLSX: "parse-tkb-xslx",
PROCESS_PARSE_TKB_XLSX_RESULT: "process-parse-tkb-xlsx-result"
PROCESS_PARSE_TKB_XLSX_RESULT: "process-parse-tkb-xlsx-result",
RUN_JOB: "run-job",
PROCESS_JOB_RESULT: "process-job-result",
RUN_JOB_V1: "run-job-v1",
PROCESS_JOB_V1_RESULT: "process-job-v1-result",
RUN_JOB_V2: "run-job-v2",
PROCESS_JOB_V2_RESULT: "process-job-v2-result",
};

export const AppEvent = {
Expand All @@ -54,4 +68,24 @@ export const AppEvent = {
REPLACE_TERM_IDS: "replace-term-ids",
UPSERT_MANY_SUBJECTS: "upsert-many-subjects",
UPSERT_MANY_CTR: "upsert-many-class-to-registers",
};
NEW_JOB: random.nextStr(),
NEW_JOB_RESULT: random.nextStr(),
STALE_JOB: random.nextStr(),
NEW_JOB_V1: random.nextStr(),
NEW_JOB_V1_RESULT: random.nextStr(), // deprecated
JOB_V1_UNKNOWN_ERROR: random.nextStr(),
JOB_V1_SYSTEM_ERROR: random.nextStr(),
JOB_V1_CAPTCHA_ERROR: random.nextStr(),
JOB_V1_DONE: random.nextStr(),
NEW_JOB_V2: random.nextStr(),
NEW_JOB_V2_RESULT: random.nextStr(),
STALE_JOB_V2: random.nextStr(),
};

export const ExchangeName = {
WORKER_PING: "worker-ping",
WORKER_DOING: "worker-doing",
MAYBE_STALE_JOB: "maybe-stale-job",
MAYBE_STALE_JOB_V1: "maybe-stale-job-v1",
MAYBE_STALE_JOB_V2: "maybe-stale-job-v2",
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const setup = () => {

rabbitmqConnectionPool.getChannel().consume(q.queue, async (msg) => {
try {
const result = JSON.parse(c(cfg.AMQP_ENCRYPTION_KEY).d(msg.content.toString(), msg.properties.headers.iv));
const result = JSON.parse(c(cfg.AMQP_ENCRYPTION_KEY, msg.properties.headers.iv).d(msg.content.toString()));

const doc = await mongoConnectionPool.getClient()
.db(cfg.DATABASE_NAME)
Expand All @@ -35,8 +35,8 @@ export const setup = () => {
jobId: job._id,
workerId: result.workerId,
ownerAccountId: job.ownerAccountId,
logs: c(cfg.JOB_ENCRYPTION_KEY).e(toJson(result.logs), newIv),
vars: c(cfg.JOB_ENCRYPTION_KEY).e(toJson(result.vars), newIv),
logs: c(cfg.JOB_ENCRYPTION_KEY, newIv).e(toJson(result.logs)),
vars: c(cfg.JOB_ENCRYPTION_KEY, newIv).e(toJson(result.vars)),
createdAt: Date.now(),
iv: newIv,
});
Expand Down
24 changes: 10 additions & 14 deletions api-gateway/src/cypher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,28 @@ import crypto from "crypto";
const ALGORITHM = "aes-256-cbc";

class Cypher {
secret: string;
_iv: string;
__secret: string;
__iv: string;

constructor(secret: string) {
this.secret = secret;
constructor(secret: string, iv: string) {
this.__secret = secret;
this.__iv = iv;
}

iv(iv: string) {
this._iv = iv;
return this;
}

encrypt(text: string) {
const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(this.secret, "hex"), Buffer.from(this._iv, "hex"));
e(text: string) {
const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(this.__secret, "hex"), Buffer.from(this.__iv, "hex"));
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return encrypted.toString("hex");
}

decrypt(text: string) {
d(text: string) {
const encryptedText = Buffer.from(text, "hex");
const decipher = crypto.createDecipheriv(ALGORITHM, Buffer.from(this.secret, "hex"), Buffer.from(this._iv, "hex"));
const decipher = crypto.createDecipheriv(ALGORITHM, Buffer.from(this.__secret, "hex"), Buffer.from(this.__iv, "hex"));
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
}
}

export const c = (secret: string) => new Cypher(secret);
export const c = (secret: string, iv: string) => new Cypher(secret, iv);
24 changes: 12 additions & 12 deletions api-gateway/src/dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { ParsedClassToRegister } from "./payloads";
export const dropPassword = (input: unknown) => modify(input, [m.drop(["password"])]);

export const decryptJobV1 = (input: DKHPTDJobV1) => {
const dPassword = c(cfg.JOB_ENCRYPTION_KEY).iv(input.iv).decrypt(input.password);
const dUsername = c(cfg.JOB_ENCRYPTION_KEY).iv(input.iv).decrypt(input.username);
const dPassword = c(cfg.JOB_ENCRYPTION_KEY, input.iv).d(input.password);
const dUsername = c(cfg.JOB_ENCRYPTION_KEY, input.iv).d(input.username);
return {
_id: input._id,
ownerAccountId: input.ownerAccountId,
Expand All @@ -28,8 +28,8 @@ export const decryptJobV1 = (input: DKHPTDJobV1) => {

export const encryptJobV1 = (input: DKHPTDJobV1) => {
const iv = crypto.randomBytes(16).toString("hex");
const ePassword = c(cfg.JOB_ENCRYPTION_KEY).iv(iv).encrypt(input.password);
const eUsername = c(cfg.JOB_ENCRYPTION_KEY).iv(iv).encrypt(input.username);
const ePassword = c(cfg.JOB_ENCRYPTION_KEY, iv).e(input.password);
const eUsername = c(cfg.JOB_ENCRYPTION_KEY, iv).e(input.username);
return {
_id: input._id,
ownerAccountId: input.ownerAccountId,
Expand All @@ -47,8 +47,8 @@ export const encryptJobV1 = (input: DKHPTDJobV1) => {
};

export const decryptJobV2 = (input: DKHPTDJobV2) => {
const dPassword = c(cfg.JOB_ENCRYPTION_KEY).iv(input.iv).decrypt(input.password);
const dUsername = c(cfg.JOB_ENCRYPTION_KEY).iv(input.iv).decrypt(input.username);
const dPassword = c(cfg.JOB_ENCRYPTION_KEY, input.iv).d(input.password);
const dUsername = c(cfg.JOB_ENCRYPTION_KEY, input.iv).d(input.username);
return new DKHPTDJobV2({
_id: input._id,
ownerAccountId: input.ownerAccountId,
Expand All @@ -64,8 +64,8 @@ export const decryptJobV2 = (input: DKHPTDJobV2) => {

export const encryptJobV2 = (input: DKHPTDJobV2) => {
const iv = crypto.randomBytes(16).toString("hex");
const ePassword = c(cfg.JOB_ENCRYPTION_KEY).iv(iv).encrypt(input.password);
const eUsername = c(cfg.JOB_ENCRYPTION_KEY).iv(iv).encrypt(input.username);
const ePassword = c(cfg.JOB_ENCRYPTION_KEY, iv).e(input.password);
const eUsername = c(cfg.JOB_ENCRYPTION_KEY, iv).e(input.username);
return new DKHPTDJobV2({
_id: input._id,
ownerAccountId: input.ownerAccountId,
Expand All @@ -81,8 +81,8 @@ export const encryptJobV2 = (input: DKHPTDJobV2) => {
};

export const decryptJobV1Result = (input: DKHPTDJobV1Result) => {
const logs: [] = input.logs ? JSON.parse(c(cfg.JOB_ENCRYPTION_KEY).iv(input.iv).decrypt(input.logs,)) : [];
const vars = input.vars ? JSON.parse(c(cfg.JOB_ENCRYPTION_KEY).iv(input.iv).decrypt(input.vars)) : {};
const logs: [] = input.logs ? JSON.parse(c(cfg.JOB_ENCRYPTION_KEY, input.iv).d(input.logs,)) : [];
const vars = input.vars ? JSON.parse(c(cfg.JOB_ENCRYPTION_KEY, input.iv).d(input.vars)) : {};
return new DKHPTDJobResult({
_id: input._id,
jobId: input.jobId,
Expand All @@ -95,8 +95,8 @@ export const decryptJobV1Result = (input: DKHPTDJobV1Result) => {
};

export const decryptJobV2Result = (input: DKHPTDJobV2Result) => {
const logs: [] = input.logs ? JSON.parse(c(cfg.JOB_ENCRYPTION_KEY).iv(input.iv).decrypt(input.logs)) : [];
const vars = input.vars ? JSON.parse(c(cfg.JOB_ENCRYPTION_KEY).iv(input.iv).decrypt(input.vars)) : {};
const logs: [] = input.logs ? JSON.parse(c(cfg.JOB_ENCRYPTION_KEY, input.iv).d(input.logs)) : [];
const vars = input.vars ? JSON.parse(c(cfg.JOB_ENCRYPTION_KEY, input.iv).d(input.vars)) : {};
return new DKHPTDJobResult({
_id: input._id,
jobId: input.jobId,
Expand Down
File renamed without changes.
9 changes: 8 additions & 1 deletion api-gateway/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,11 @@ export const toSafeInt = (input) => parseInt(input) || 0;
export const toSafeString = (input) => String(input);
export const toSHA256 = (input: string) => crypto.createHash("sha256").update(input).digest("hex");

export const ensureIndex = async (db: Db, collectionName: string, def: IndexSpecification) => db.collection(collectionName).createIndex(def);
export const ensureIndex = async (db: Db, collectionName: string, def: IndexSpecification) => db.collection(collectionName).createIndex(def);

let __n = 0;

export const random = {
nextInt: () => __n++,
nextStr: () => String(__n++)
}
Loading

0 comments on commit 773e7b6

Please sign in to comment.