fix: harden UCE runtime and starter
This commit is contained in:
@@ -4,7 +4,7 @@ COMPONENT(Request& context)
|
||||
{
|
||||
String title = first(context.props["title"].to_string(), "Sign in with OAuth");
|
||||
String subtitle = first(context.props["subtitle"].to_string(), "Choose your preferred authentication method");
|
||||
String callback_url = first(context.props["callback_url"].to_string(), starter_link("auth/callback", context));
|
||||
String callback_url = first(context.props["callback_url"].to_string(), app_link("auth/callback", context));
|
||||
|
||||
DTree services = context.props["services"];
|
||||
if(services.get_type_name() != "array" || services["google"]["name"].to_string() == "")
|
||||
@@ -46,7 +46,7 @@ COMPONENT(Request& context)
|
||||
String service_name = service["name"].to_string();
|
||||
String scope = service["scope"].to_string();
|
||||
String auth_url = service["auth_url"].to_string();
|
||||
String store_url = starter_link("auth/store-oauth-session", context);
|
||||
String store_url = app_link("auth/store-oauth-session", context);
|
||||
?><div data-service="<?= service_key ?>">
|
||||
<button type="button" class="btn" onclick='initiateOAuth_<?= handler_name ?>()'>
|
||||
<i class="<?= service["icon"].to_string() ?>" style="color: <?= service["color"].to_string() ?>"></i>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_boot(context);
|
||||
|
||||
<>
|
||||
<div id="cookie-consent" style="
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#load "../../lib/app.uce"
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
String message = first(context.props["message"].to_string(), "The requested page does not exist.");
|
||||
context.set_status(404, "Not Found");
|
||||
context.call["app"]["page_title"] = "404 Not Found";
|
||||
<>
|
||||
<section class="card">
|
||||
<h1>404 Not Found</h1>
|
||||
<p><?= message ?></p>
|
||||
<p>The starter router looked for the route as an exact view, a directory index, and then parent index handlers.</p>
|
||||
</section>
|
||||
</>
|
||||
}
|
||||
@@ -1,5 +1,15 @@
|
||||
#load "../../lib/app.uce"
|
||||
|
||||
ONCE(Request& context)
|
||||
{
|
||||
?><link rel="stylesheet" href="<?= app_asset_url("js/ag-grid/ag-grid.css", context) ?>" />
|
||||
<link rel="stylesheet" href="<?= app_asset_url("js/ag-grid/ag-theme-alpine.css", context) ?>" />
|
||||
<script src="<?= app_asset_url("js/u-format.js", context) ?>"></script>
|
||||
<script src="<?= app_asset_url("js/u-timeseries-chart.js", context) ?>"></script>
|
||||
<script src="<?= app_asset_url("js/u-sortable-table.js", context) ?>"></script>
|
||||
<script src="<?= app_asset_url("js/ag-grid/ag-grid-community.min.js", context) ?>"></script><?
|
||||
}
|
||||
|
||||
String data_format_bytes(String raw, bool disk = false)
|
||||
{
|
||||
if(trim(raw) == "")
|
||||
@@ -105,8 +115,6 @@ COMPONENT:SUMMARY_METRICS(Request& context)
|
||||
|
||||
COMPONENT:TIMESERIES_CHART(Request& context)
|
||||
{
|
||||
starter_register_js("js/u-format.js", context);
|
||||
starter_register_js("js/u-timeseries-chart.js", context);
|
||||
|
||||
String chart_id = first(context.props["id"].to_string(), "ts-chart-" + std::to_string((u64)time()));
|
||||
String canvas_id = chart_id + "-canvas";
|
||||
@@ -148,8 +156,6 @@ COMPONENT:TIMESERIES_CHART(Request& context)
|
||||
|
||||
COMPONENT:SORTABLE_TABLE(Request& context)
|
||||
{
|
||||
starter_register_js("js/u-format.js", context);
|
||||
starter_register_js("js/u-sortable-table.js", context);
|
||||
|
||||
String table_id = first(context.props["id"].to_string(), "sortable-table-" + std::to_string((u64)time()));
|
||||
String title = context.props["title"].to_string();
|
||||
@@ -214,9 +220,6 @@ COMPONENT:SORTABLE_TABLE(Request& context)
|
||||
COMPONENT:DATA_TABLE(Request& context)
|
||||
{
|
||||
String table_id = first(context.props["id"].to_string(), "data-grid-" + std::to_string((u64)time()));
|
||||
starter_register_js("js/ag-grid/ag-grid-community.min.js", context);
|
||||
starter_register_css("js/ag-grid/ag-grid.css", context);
|
||||
starter_register_css("js/ag-grid/ag-theme-alpine.css", context);
|
||||
|
||||
DTree columns = context.props["columns"];
|
||||
if(columns.get_type_name() != "array")
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_boot(context);
|
||||
String current_theme = context.cfg.get_by_path("theme/key").to_string();
|
||||
String current_label = first(context.cfg.get_by_path("theme/label").to_string(), current_theme);
|
||||
String route_path = context.call["starter"]["route"]["l_path"].to_string();
|
||||
String route_path = context.call["route"]["l_path"].to_string();
|
||||
|
||||
<>
|
||||
<div id="theme-switcher" style="position: fixed; right: 1.5rem; bottom: 1.5rem; z-index: 9999; font-family: inherit;">
|
||||
@@ -111,7 +110,7 @@ COMPONENT(Request& context)
|
||||
<? context.cfg.get_by_path("theme/options").each([&](DTree theme_info, String theme_key) {
|
||||
StringMap params;
|
||||
params["theme"] = theme_key;
|
||||
String href = starter_link(route_path == "index" ? "" : route_path, params, context);
|
||||
String href = app_link(route_path == "index" ? "" : route_path, params, context);
|
||||
?><a class="theme-option<?= theme_key == current_theme ? " is-active" : "" ?>" href="<?= href ?>">
|
||||
<span><?= theme_info["label"].to_string() ?></span>
|
||||
<? if(theme_key == current_theme) { ?><small>Active</small><? } ?>
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_register_js("components/gauges/common.js", context);
|
||||
starter_register_css("themes/common/css/gauges.css", context);
|
||||
DTree asset_props;
|
||||
asset_props["css"]["0"] = "themes/common/css/gauges.css";
|
||||
asset_props["js"]["0"] = "components/gauges/common.js";
|
||||
print(component("../theme/assets", asset_props, context));
|
||||
|
||||
String gauge_id = first(context.props["id"].to_string(), "arcgauge-" + std::to_string((u64)time()));
|
||||
String title = context.props["title"].to_string();
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_register_js("components/gauges/common.js", context);
|
||||
starter_register_css("themes/common/css/gauges.css", context);
|
||||
DTree asset_props;
|
||||
asset_props["css"]["0"] = "themes/common/css/gauges.css";
|
||||
asset_props["js"]["0"] = "components/gauges/common.js";
|
||||
print(component("../theme/assets", asset_props, context));
|
||||
|
||||
String gauge_id = first(context.props["id"].to_string(), "needlegauge-" + std::to_string((u64)time()));
|
||||
String style = context.props["style"].to_string();
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_register_js("components/gauges/common.js", context);
|
||||
starter_register_css("themes/common/css/gauges.css", context);
|
||||
DTree asset_props;
|
||||
asset_props["css"]["0"] = "themes/common/css/gauges.css";
|
||||
asset_props["js"]["0"] = "components/gauges/common.js";
|
||||
print(component("../theme/assets", asset_props, context));
|
||||
|
||||
String gauge_id = first(context.props["id"].to_string(), "progressbar-" + std::to_string((u64)time()));
|
||||
String style = context.props["style"].to_string();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_boot(context);
|
||||
StarterUser users(context);
|
||||
DTree user = users.current();
|
||||
bool signed_in = user["email"].to_string() != "";
|
||||
@@ -16,14 +15,14 @@ COMPONENT(Request& context)
|
||||
<? if(signed_in) { ?>
|
||||
<span class="<?= name_class ?>"><?= first(user["username"].to_string(), user["email"].to_string(), "Account") ?></span>
|
||||
<? if(links_class != "") { ?><div class="<?= links_class ?>"><? } ?>
|
||||
<a href="<?= starter_link("account/profile", context) ?>">Profile</a>
|
||||
<a href="<?= starter_link("account/logout", context) ?>">Logout</a>
|
||||
<a href="<?= app_link("account/profile", context) ?>">Profile</a>
|
||||
<a href="<?= app_link("account/logout", context) ?>">Logout</a>
|
||||
<? if(links_class != "") { ?></div><? } ?>
|
||||
<? } else { ?>
|
||||
<? if(links_class != "") { ?><div class="<?= links_class ?>"><? } ?>
|
||||
<a href="<?= starter_link("account/login", context) ?>">Login</a>
|
||||
<a href="<?= app_link("account/login", context) ?>">Login</a>
|
||||
<? if(context.cfg.get_by_path("users/enable_signup").to_string() != "") { ?>
|
||||
<a href="<?= starter_link("account/register", context) ?>">Register</a>
|
||||
<a href="<?= app_link("account/register", context) ?>">Register</a>
|
||||
<? } ?>
|
||||
<? if(links_class != "") { ?></div><? } ?>
|
||||
<? } ?>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#load "../../lib/app.uce"
|
||||
|
||||
void app_asset_tag_once(Request& context, String kind, String path)
|
||||
{
|
||||
if(path == "")
|
||||
return;
|
||||
String key = kind + ":" + path;
|
||||
if(context.call["assets"][key].to_bool())
|
||||
return;
|
||||
context.call["assets"][key].set_bool(true);
|
||||
if(kind == "css")
|
||||
{
|
||||
?><link rel="stylesheet" href="<?= app_asset_url(path, context) ?>" /><?
|
||||
}
|
||||
else if(kind == "js")
|
||||
{
|
||||
?><script src="<?= app_asset_url(path, context) ?>"></script><?
|
||||
}
|
||||
}
|
||||
|
||||
void app_asset_tags(Request& context, String kind, DTree assets)
|
||||
{
|
||||
String scalar = assets.to_string();
|
||||
if(scalar != "")
|
||||
{
|
||||
app_asset_tag_once(context, kind, scalar);
|
||||
return;
|
||||
}
|
||||
assets.each([&](DTree item, String key) {
|
||||
app_asset_tag_once(context, kind, item.to_string());
|
||||
});
|
||||
}
|
||||
|
||||
COMPONENT(Request& context)
|
||||
@fragment head
|
||||
{
|
||||
app_asset_tags(context, "css", context.props["css"]);
|
||||
app_asset_tags(context, "js", context.props["js"]);
|
||||
}
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_boot(context);
|
||||
bool embed_mode = starter_page_embed_mode(context);
|
||||
if(embed_mode)
|
||||
return;
|
||||
|
||||
String text = first(context.cfg.get_by_path("theme/footer_text").to_string(), context.cfg.get_by_path("site/name").to_string());
|
||||
String inner_class = first(context.props["inner_class"].to_string(), context.cfg.get_by_path("theme/key").to_string() == "portal-light" ? "footer-inner" : "");
|
||||
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_boot(context);
|
||||
if(starter_page_embed_mode(context))
|
||||
return;
|
||||
|
||||
String cookie_value = context.props["cookie_consent"].to_string();
|
||||
bool cookie_consent = !(cookie_value == "0" || cookie_value == "false" || cookie_value == "FALSE" || cookie_value == "no" || cookie_value == "NO");
|
||||
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_boot(context);
|
||||
String title = first(context.call["starter"]["page_title"].to_string(), context.cfg.get_by_path("site/default_page_title").to_string());
|
||||
String title = first(context.call["app"]["page_title"].to_string(), context.cfg.get_by_path("site/default_page_title").to_string());
|
||||
String description = first(context.cfg.get_by_path("theme/meta_description").to_string(), "UCE starter example");
|
||||
String theme_color = first(context.cfg.get_by_path("theme/theme_color").to_string(), "#0f172a");
|
||||
String icon = starter_asset_url(context.cfg.get_by_path("theme/path").to_string() + "icon.png", context);
|
||||
String icon = app_asset_url(context.cfg.get_by_path("theme/path").to_string() + "icon.png", context);
|
||||
|
||||
<>
|
||||
<meta charset="utf-8">
|
||||
@@ -16,7 +15,11 @@ COMPONENT(Request& context)
|
||||
<meta name="theme-color" content="<?= theme_color ?>">
|
||||
<link rel="apple-touch-icon" href="<?= icon ?>" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="<?= icon ?>" />
|
||||
<? starter_render_registered_css(context); ?>
|
||||
<? starter_render_registered_js(context); ?>
|
||||
<link rel="stylesheet" href="<?= app_asset_url(context.cfg.get_by_path("theme/path").to_string() + "css/style.css", context) ?>" />
|
||||
<link rel="stylesheet" href="<?= app_asset_url("themes/common/fontawesome/css/all.min.css", context) ?>" />
|
||||
<script src="<?= app_asset_url("js/u-query.js", context) ?>"></script>
|
||||
<script src="<?= app_asset_url("js/morphdom.js", context) ?>"></script>
|
||||
<script src="<?= app_asset_url("js/site.js", context) ?>"></script>
|
||||
<?: context.call["fragments"]["head"].to_string() ?>
|
||||
</>
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#load "../../lib/app.uce"
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_boot(context);
|
||||
if(context.props["main_html"].to_string() != "")
|
||||
context.call["starter"]["fragments"]["main"] = context.props["main_html"];
|
||||
if(context.props["json"].get_type_name() == "array")
|
||||
context.call["starter"]["json"] = context.props["json"];
|
||||
if(context.props["page_type"].to_string() != "")
|
||||
context.call["starter"]["page_type"] = context.props["page_type"];
|
||||
if(context.props["embed_mode"].to_string() != "")
|
||||
context.call["starter"]["embed_mode"] = context.props["embed_mode"];
|
||||
starter_render_page(context);
|
||||
}
|
||||
|
||||
COMPONENT:HEAD(Request& context)
|
||||
{
|
||||
print(component("head", context.props, context));
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
starter_boot(context);
|
||||
String nav_class = context.props["nav_class"].to_string();
|
||||
if(nav_class == "" && (context.cfg.get_by_path("theme/key").to_string() == "portal-dark" || context.cfg.get_by_path("theme/key").to_string() == "dark" || context.cfg.get_by_path("theme/key").to_string() == "retro-gaming"))
|
||||
nav_class = "nav-shell";
|
||||
@@ -18,11 +17,12 @@ COMPONENT(Request& context)
|
||||
<>
|
||||
<nav<?: nav_class != "" ? " class=\"" + html_escape(nav_class) + "\"" : "" ?>>
|
||||
<div class="nav-menu">
|
||||
<a href="<?= starter_link("", context) ?>"><?= context.cfg.get_by_path("site/name").to_string() ?></a>
|
||||
<a href="<?= app_link("", context) ?>"><?= context.cfg.get_by_path("site/name").to_string() ?></a>
|
||||
<? context.cfg.get_by_path("menu").each([&](DTree menu_item, String menu_key) {
|
||||
if(menu_item["hidden"].to_string() == "1")
|
||||
return;
|
||||
?><a href="<?= starter_menu_href(menu_key, menu_item, context) ?>"><?= menu_item["title"].to_string() ?></a><?
|
||||
String href = menu_item["external"].to_string() != "" ? "/" + menu_key : app_link(menu_key, context);
|
||||
?><a href="<?= href ?>"><?= menu_item["title"].to_string() ?></a><?
|
||||
}); ?>
|
||||
</div>
|
||||
<?: component("account_links", account_props, context) ?>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#load "../../lib/app.uce"
|
||||
|
||||
COMPONENT:island(Request& context)
|
||||
{
|
||||
String name = context.props["name"].to_string();
|
||||
String module = context.props["module"].to_string();
|
||||
String id = first(context.props["id"].to_string(), "island-" + ascii_safe_name(name));
|
||||
String payload = json_encode(context.props["props"]);
|
||||
if(name == "")
|
||||
return;
|
||||
<>
|
||||
<div id="<?= id ?>" data-uce-island="<?= name ?>" data-props="<?: html_escape(payload) ?>"></div>
|
||||
</>
|
||||
if(module != "")
|
||||
{
|
||||
<><script type="module" src="<?= app_asset_url(module, context) ?>"></script></>
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
#load "../../lib/app.uce"
|
||||
|
||||
ONCE(Request& context)
|
||||
{
|
||||
?><link rel="stylesheet" href="<?= app_asset_url("themes/common/css/workspace.css", context) ?>" />
|
||||
<script src="<?= app_asset_url("js/u-workspace-shell.js", context) ?>"></script><?
|
||||
}
|
||||
|
||||
COMPONENT:APP_FRAME(Request& context)
|
||||
{
|
||||
starter_register_css("themes/common/css/workspace.css", context);
|
||||
starter_register_js("js/u-workspace-shell.js", context);
|
||||
String id = context.props["id"].to_string();
|
||||
String overlay_id = context.props["overlay_id"].to_string();
|
||||
String class_name = context.props["class"].to_string();
|
||||
|
||||
Reference in New Issue
Block a user