!7 concept Domain { S domain; S moduleLibID; bool mustBeEnabled; toString { ret super.toString() + " " + domain; } } cmodule2 Eleu3 > DynEleu { transient CRUD domainCRUD; switchable bool verbose; switchable bool debugNanoHTTPD; switchable S sameSite; start { NanoHTTPD_debug = debugNanoHTTPD; dbIndexingCI(Domain, 'domain); uniqCI Domain(domain := ""); domainCRUD = new CRUD(Domain); } visual jtabs( "Main", super, "Domains" := domainCRUD.visualize()); @Override S moduleForDomain(S domain) { for (Domain d : domainsInMatchingOrder()) { if (domainIsUnder(domain, d.domain)) { S mod = findMod(d); if (verbose) print("Domain matched: " + domain + " / " + d.domain + " => " + mod); try answer mod; } else if (verbose) print("Domain not matched: " + domain + " / " + d.domain); } ret findMod(defaultDomain()); } Domain defaultDomain() { ret conceptWhereCI Domain(domain := ""); } S findMod(Domain d) { if (d == null) null; ret d.mustBeEnabled ? dm_findModuleWithParams(d.moduleLibID, enabled := true) : dm_findModule(d.moduleLibID); } ServeHttp_CookieHandler makeCookieHandler() { ServeHttp_CookieHandler cookieHandler = super.makeCookieHandler(); cookieHandler.metaParams = appendPrefixIfNempty("SameSite=", sameSite); ret cookieHandler; } // API Cl domainsInMatchingOrder() { ret sortByCalculatedFieldICDesc( filter(list(Domain), d -> !eqic(d.domain, "")), d -> reversed(d.domain)); } }