fix(build): render Nextcloud login page via askama, not include_str!(OUT_DIR)
The SvelteKit migration gated build.rs's static-dist/OUT_DIR generation
behind OXICLOUD_RUST_ASSETS=1 (early return), but login_v2_handler.rs
still embedded the page with
`include_str!(concat!(env!("OUT_DIR"), "/nextcloud-login.html"))`. With
OXICLOUD_RUST_ASSETS unset (the default), that file is never written to
OUT_DIR, so a clean `cargo build` failed to compile. (#489)
Migrate the page off include_str! to an askama template
(templates/nextcloud/login.html), mirroring the existing
DrivePickerTemplate in the same handler. This drops the only
compile-time dependency on the legacy build.rs pipeline, so the
OXICLOUD_RUST_ASSETS=1 CI workaround is no longer needed and is removed
from ci.yml, load-smoke.yml and load-nightly.yml.
Also fix the second failure on #489: with OXICLOUD_RUST_ASSETS=1 the
release pipeline panicked in copy_dir_recursive because `static/locales`
is now a symlink to frontend/static/locales. entry.file_type() reports
the link itself (not its target), so the symlinked directory was routed
to fs::copy and failed with "the source path is neither a regular file
nor a symlink to a regular file". Classify entries with fs::metadata,
which follows symlinks, so symlinked directories are traversed.
static/nextcloud-login.html is removed (its content moved into the
template; no other consumer) and dropped from build.rs HTML_INCLUDE.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CNCEMN6fC2xSmxqCVbstkd
This commit is contained in:
@@ -29,6 +29,14 @@ struct DrivePickerTemplate {
|
||||
drives: Vec<DriveOption>,
|
||||
}
|
||||
|
||||
/// The Nextcloud Login Flow v2 "Grant Access" page. Rendered server-side via
|
||||
/// askama (no template variables — the username/password are collected by the
|
||||
/// embedded form) instead of `include_str!` so the build no longer depends on
|
||||
/// the legacy `build.rs` static-asset pipeline / `OUT_DIR`.
|
||||
#[derive(Template)]
|
||||
#[template(path = "nextcloud/login.html")]
|
||||
struct NextcloudLoginTemplate;
|
||||
|
||||
// Home identification is via `position_of_user_home_root_folder` from
|
||||
// `domain::repositories::drive_repository` — a generic helper that
|
||||
// keys off `drives.default_for_user == user_id` rather than folder
|
||||
@@ -36,7 +44,7 @@ struct DrivePickerTemplate {
|
||||
// picker UX.
|
||||
|
||||
/// Serve an HTML page with a Content-Security-Policy header as defense-in-depth.
|
||||
fn html_with_csp(html: &'static str) -> Response {
|
||||
fn html_with_csp(html: String) -> Response {
|
||||
(
|
||||
[(
|
||||
header::CONTENT_SECURITY_POLICY,
|
||||
@@ -160,10 +168,13 @@ pub async fn handle_login_page(
|
||||
return StatusCode::NOT_FOUND.into_response();
|
||||
}
|
||||
|
||||
html_with_csp(include_str!(concat!(
|
||||
env!("OUT_DIR"),
|
||||
"/nextcloud-login.html"
|
||||
)))
|
||||
match NextcloudLoginTemplate.render() {
|
||||
Ok(html) => html_with_csp(html),
|
||||
Err(e) => {
|
||||
tracing::error!(error = %e, "Login Flow v2: login page template render failed");
|
||||
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle_login_submit(
|
||||
|
||||
Reference in New Issue
Block a user