thelounge/server/plugins/sts.ts

109 lines
2.2 KiB
TypeScript
Raw Normal View History

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
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 {
stsFile: string;
refresh: _.DebouncedFunc<any>;
private policies: PolicyMap;
2020-02-19 11:20:22 +00:00
constructor() {
this.stsFile = path.join(Config.getHomePath(), "sts-policies.json");
2020-02-19 11:20:22 +00:00
this.policies = new Map();
// 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;
}
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,
duration: value.duration,
2020-02-19 11:20:22 +00:00
expires: value.expires,
});
}
});
}
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;
}
update(host: string, port: number, duration: number) {
2020-02-19 11:20:22 +00:00
if (duration > 0) {
this.policies.set(host, {
port: port,
duration: duration,
2020-02-19 11:20:22 +00:00
expires: Date.now() + duration * 1000,
});
} else {
this.policies.delete(host);
}
this.refresh();
}
refreshExpiration(host: string) {
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() {
const policiesToStore: PolicyOption[] = [];
2020-02-19 11:20:22 +00:00
this.policies.forEach((value, key) => {
policiesToStore.push({
host: key,
port: value.port,
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) {
log.error("Failed to update STS policies file!", err.message);
2020-02-19 11:20:22 +00:00
}
});
}
}
export default new STSPolicies();