import { IService, Request, Response, Service } from "../../../mod.ts";
type ReferrerPolicy = | "" | "no-referrer" | "no-referrer-when-downgrade" | "same-origin" | "origin" | "strict-origin" | "origin-when-cross-origin" | "strict-origin-when-cross-origin" | "unsafe-url";
type HSTS = { max_age?: boolean | number; include_sub_domains?: boolean; preload?: boolean;};
interface Configs { "X-XSS-Protection"?: boolean; "Referrer-Policy"?: ReferrerPolicy; "X-Content-Type-Options"?: boolean; hsts?: HSTS; "X-Powered-By"?: boolean | string; "X-Frame-Options"?: "DENY" | "SAMEORIGIN" | boolean | string ; expect_ct?: { enforce?: boolean; max_age?: number; report_uri?: string; }; "X-DNS-Prefetch-Control"?: boolean; "Content-Security-Policy"?: string;}
export class PaladinService extends Service implements IService { readonly #configs: Configs; constructor(configs: Configs = {}) { super(); if (!configs.hsts) { configs.hsts = {}; } if (!configs.expect_ct) { configs.expect_ct = {}; } this.#configs = configs; }
runAfterResource(_request: Request, response: Response) { if ( this.#configs["X-XSS-Protection"] === true || this.#configs["X-XSS-Protection"] !== false ) { response.headers.set( "X-XSS-Protection", "1; mode=block", ); }
if (this.#configs["Referrer-Policy"]) { response.headers.set( "Referrer-Policy", this.#configs["Referrer-Policy"], ); }
if ( this.#configs["X-Content-Type-Options"] === true || this.#configs["X-Content-Type-Options"] !== false ) { response.headers.set( "X-Content-Type-Options", "nosniff", ); }
let hstsHeader = ""; if (typeof this.#configs.hsts!.max_age === "number") { hstsHeader += "max-age=" + this.#configs.hsts!.max_age; } else if (this.#configs.hsts!.max_age !== false) { hstsHeader += "max-age=" + 5184000; } if ( hstsHeader && (this.#configs.hsts!.include_sub_domains === true || this.#configs.hsts!.include_sub_domains !== false) ) { hstsHeader += "; include_sub_domains"; } if (hstsHeader && this.#configs.hsts!.preload === true) { hstsHeader += "; preload"; } if (hstsHeader) { response.headers.set("Strict-Transport-Security", hstsHeader); }
if (typeof this.#configs["X-Powered-By"] === "string") { response.headers.set( "X-Powered-By", this.#configs["X-Powered-By"] as string, ); } else if (this.#configs["X-Powered-By"] !== true) { response.headers.delete("X-Powered-By"); }
if (typeof this.#configs["X-Frame-Options"] === "string") { response.headers.set( "X-Frame-Options", this.#configs["X-Frame-Options"] as string, ); } else if (this.#configs["X-Frame-Options"] !== false) { response.headers.set( "X-Frame-Options", "SAMEORIGIN", ); }
let expectCTHeader = ""; if (this.#configs.expect_ct!.max_age) { expectCTHeader += "max-age=" + this.#configs.expect_ct!.max_age; } if (expectCTHeader && this.#configs.expect_ct!.enforce === true) { expectCTHeader += "; enforce"; } if (expectCTHeader && this.#configs.expect_ct!.report_uri) { expectCTHeader += "; " + this.#configs.expect_ct!.report_uri; } if (expectCTHeader) { response.headers.set("Expect-CT", expectCTHeader); }
if (this.#configs["X-DNS-Prefetch-Control"] === true) { response.headers.set("X-DNS-Prefetch-Control", "on"); } else { response.headers.set("X-DNS-Prefetch-Control", "off"); }
if (this.#configs["Content-Security-Policy"]) { response.headers.set( "Content-Security-Policy", this.#configs["Content-Security-Policy"], ); } }}