2022-06-19 00:25:21 +00:00
|
|
|
import _ from "lodash";
|
|
|
|
import fs from "fs";
|
|
|
|
import path from "path";
|
|
|
|
import log from "../log";
|
|
|
|
import Config from "../config";
|
2020-02-19 11:20:22 +00:00
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
type PolicyOption = {
|
|
|
|
port: number;
|
|
|
|
duration: number;
|
|
|
|
expires: number;
|
|
|
|
host: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
type PolicyMap = Map<string, Omit<PolicyOption, "host">>;
|
2020-02-19 11:20:22 +00:00
|
|
|
|
|
|
|
class STSPolicies {
|
2022-06-19 00:25:21 +00:00
|
|
|
stsFile: string;
|
|
|
|
refresh: _.DebouncedFunc<any>;
|
|
|
|
|
|
|
|
private policies: PolicyMap;
|
|
|
|
|
2020-02-19 11:20:22 +00:00
|
|
|
constructor() {
|
2022-05-01 19:12:39 +00:00
|
|
|
this.stsFile = path.join(Config.getHomePath(), "sts-policies.json");
|
2020-02-19 11:20:22 +00:00
|
|
|
this.policies = new Map();
|
2022-06-19 00:25:21 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
2020-02-19 11:20:22 +00:00
|
|
|
this.refresh = _.debounce(this.saveFile, 10000, {maxWait: 60000});
|
|
|
|
|
|
|
|
if (!fs.existsSync(this.stsFile)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
const storedPolicies = JSON.parse(fs.readFileSync(this.stsFile, "utf-8")) as PolicyOption[];
|
2020-02-19 11:20:22 +00:00
|
|
|
const now = Date.now();
|
|
|
|
|
|
|
|
storedPolicies.forEach((value) => {
|
|
|
|
if (value.expires > now) {
|
|
|
|
this.policies.set(value.host, {
|
|
|
|
port: value.port,
|
2020-02-19 12:09:22 +00:00
|
|
|
duration: value.duration,
|
2020-02-19 11:20:22 +00:00
|
|
|
expires: value.expires,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
get(host: string) {
|
2020-02-19 11:20:22 +00:00
|
|
|
const policy = this.policies.get(host);
|
|
|
|
|
|
|
|
if (typeof policy === "undefined") {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (policy.expires <= Date.now()) {
|
|
|
|
this.policies.delete(host);
|
|
|
|
this.refresh();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return policy;
|
|
|
|
}
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
update(host: string, port: number, duration: number) {
|
2020-02-19 11:20:22 +00:00
|
|
|
if (duration > 0) {
|
|
|
|
this.policies.set(host, {
|
|
|
|
port: port,
|
2020-02-19 12:09:22 +00:00
|
|
|
duration: duration,
|
2020-02-19 11:20:22 +00:00
|
|
|
expires: Date.now() + duration * 1000,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.policies.delete(host);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.refresh();
|
|
|
|
}
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
refreshExpiration(host: string) {
|
2020-02-19 12:09:22 +00:00
|
|
|
const policy = this.policies.get(host);
|
|
|
|
|
|
|
|
if (typeof policy === "undefined") {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
policy.expires = Date.now() + policy.duration * 1000;
|
|
|
|
}
|
|
|
|
|
2020-02-19 11:20:22 +00:00
|
|
|
saveFile() {
|
2022-06-19 00:25:21 +00:00
|
|
|
const policiesToStore: PolicyOption[] = [];
|
2020-02-19 11:20:22 +00:00
|
|
|
|
|
|
|
this.policies.forEach((value, key) => {
|
|
|
|
policiesToStore.push({
|
|
|
|
host: key,
|
|
|
|
port: value.port,
|
2020-02-19 12:09:22 +00:00
|
|
|
duration: value.duration,
|
2020-02-19 11:20:22 +00:00
|
|
|
expires: value.expires,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
const file = JSON.stringify(policiesToStore, null, "\t");
|
|
|
|
|
|
|
|
fs.writeFile(this.stsFile, file, {flag: "w+"}, (err) => {
|
|
|
|
if (err) {
|
2022-06-19 00:25:21 +00:00
|
|
|
log.error("Failed to update STS policies file!", err.message);
|
2020-02-19 11:20:22 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
export default new STSPolicies();
|