license and some functions
This commit is contained in:
+96
-18
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Mateusz Gruszczyński @linuxiarz.pl
|
||||
* Source-Available Code / Dual-Licensed.
|
||||
*
|
||||
* Free for non-commercial and evaluation use under terms of BSL/GPLv3.
|
||||
* Commercial or production use requires a valid paid license.
|
||||
* See LICENSE file in repository root for details.
|
||||
*/
|
||||
|
||||
mod access_tokens;
|
||||
mod error;
|
||||
mod files;
|
||||
@@ -178,7 +187,11 @@ pub struct EditorSettingsRequest {
|
||||
colors_enabled: bool,
|
||||
}
|
||||
|
||||
async fn editor_settings(state: &SharedState, kind: &str, slug: &str) -> Result<(String, bool), ApiError> {
|
||||
async fn editor_settings(
|
||||
state: &SharedState,
|
||||
kind: &str,
|
||||
slug: &str,
|
||||
) -> Result<(String, bool), ApiError> {
|
||||
let row: Option<(String, i64)> = sqlx::query_as(queries::get(
|
||||
state.db.kind(),
|
||||
queries::RESOURCE_EDITOR_SETTINGS_SELECT,
|
||||
@@ -187,27 +200,70 @@ async fn editor_settings(state: &SharedState, kind: &str, slug: &str) -> Result<
|
||||
.bind(slug)
|
||||
.fetch_optional(state.db.pool())
|
||||
.await?;
|
||||
Ok(row.map(|(mode, colors)| (if mode == "full" { "full".into() } else { "simple".into() }, colors != 0))
|
||||
Ok(row
|
||||
.map(|(mode, colors)| {
|
||||
(
|
||||
if mode == "full" {
|
||||
"full".into()
|
||||
} else {
|
||||
"simple".into()
|
||||
},
|
||||
colors != 0,
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| ("simple".into(), true)))
|
||||
}
|
||||
|
||||
async fn save_editor_settings(
|
||||
state: &SharedState, headers: &HeaderMap, permission_kind: &str, permission_slug: &str,
|
||||
settings_kind: &str, settings_slug: &str, payload: EditorSettingsRequest,
|
||||
state: &SharedState,
|
||||
headers: &HeaderMap,
|
||||
permission_kind: &str,
|
||||
permission_slug: &str,
|
||||
settings_kind: &str,
|
||||
settings_slug: &str,
|
||||
payload: EditorSettingsRequest,
|
||||
) -> Result<Json<serde_json::Value>, ApiError> {
|
||||
let permission = crate::auth::resource_permission(state, permission_kind, permission_slug, bearer_token(headers))
|
||||
.await.map_err(|e| ApiError::forbidden(&e.message))?;
|
||||
let permission = crate::auth::resource_permission(
|
||||
state,
|
||||
permission_kind,
|
||||
permission_slug,
|
||||
bearer_token(headers),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| ApiError::forbidden(&e.message))?;
|
||||
if permission.as_deref() != Some("rw") {
|
||||
return Err(ApiError::forbidden("Read and write access is required to save editor settings"));
|
||||
return Err(ApiError::forbidden(
|
||||
"Read and write access is required to save editor settings",
|
||||
));
|
||||
}
|
||||
let mode = match payload.authorship_mode.as_str() { "simple" => "simple", "full" | "advanced" => "full", _ => return Err(ApiError::bad_request("Invalid authorship mode")) };
|
||||
let mode = match payload.authorship_mode.as_str() {
|
||||
"simple" => "simple",
|
||||
"full" | "advanced" => "full",
|
||||
_ => return Err(ApiError::bad_request("Invalid authorship mode")),
|
||||
};
|
||||
let mut tx = state.db.pool().begin().await?;
|
||||
sqlx::query(queries::get(state.db.kind(), queries::RESOURCE_EDITOR_SETTINGS_DELETE))
|
||||
.bind(settings_kind).bind(settings_slug).execute(&mut *tx).await?;
|
||||
sqlx::query(queries::get(state.db.kind(), queries::RESOURCE_EDITOR_SETTINGS_INSERT))
|
||||
.bind(settings_kind).bind(settings_slug).bind(mode).bind(payload.colors_enabled).execute(&mut *tx).await?;
|
||||
sqlx::query(queries::get(
|
||||
state.db.kind(),
|
||||
queries::RESOURCE_EDITOR_SETTINGS_DELETE,
|
||||
))
|
||||
.bind(settings_kind)
|
||||
.bind(settings_slug)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
sqlx::query(queries::get(
|
||||
state.db.kind(),
|
||||
queries::RESOURCE_EDITOR_SETTINGS_INSERT,
|
||||
))
|
||||
.bind(settings_kind)
|
||||
.bind(settings_slug)
|
||||
.bind(mode)
|
||||
.bind(payload.colors_enabled)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
tx.commit().await?;
|
||||
Ok(Json(serde_json::json!({"authorship_mode": mode, "colors_enabled": payload.colors_enabled})))
|
||||
Ok(Json(
|
||||
serde_json::json!({"authorship_mode": mode, "colors_enabled": payload.colors_enabled}),
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn create_workspace(
|
||||
@@ -485,9 +541,22 @@ pub async fn note_info(
|
||||
let color_slug = format!("{}/{}", workspace_slug, note_slug);
|
||||
let (global_color, note_color) = editor_colors(&state, &headers, "note", &color_slug).await?;
|
||||
let (authorship_mode, colors_enabled) = editor_settings(&state, "note", &color_slug).await?;
|
||||
let can_save_editor_settings = crate::auth::resource_permission(&state, "workspace", &workspace_slug, bearer_token(&headers)).await.ok().flatten().as_deref() == Some("rw");
|
||||
let can_save_editor_settings = crate::auth::resource_permission(
|
||||
&state,
|
||||
"workspace",
|
||||
&workspace_slug,
|
||||
bearer_token(&headers),
|
||||
)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.as_deref()
|
||||
== Some("rw");
|
||||
|
||||
if workspace.is_private == 0 && !db::note_public_page_disabled(&state.db, note.id).await? && !db::note_public_page_enabled(&state.db, note.id).await? {
|
||||
if workspace.is_private == 0
|
||||
&& !db::note_public_page_disabled(&state.db, note.id).await?
|
||||
&& !db::note_public_page_enabled(&state.db, note.id).await?
|
||||
{
|
||||
db::publish_note(&state.db, note.id).await?;
|
||||
}
|
||||
Ok(Json(NoteInfo {
|
||||
@@ -533,12 +602,22 @@ pub async fn note_info(
|
||||
}
|
||||
|
||||
pub async fn set_note_editor_settings(
|
||||
State(state): State<SharedState>, headers: HeaderMap,
|
||||
State(state): State<SharedState>,
|
||||
headers: HeaderMap,
|
||||
Path((workspace_slug, note_slug)): Path<(String, String)>,
|
||||
Json(payload): Json<EditorSettingsRequest>,
|
||||
) -> Result<Json<serde_json::Value>, ApiError> {
|
||||
let settings_slug = format!("{}/{}", workspace_slug, note_slug);
|
||||
save_editor_settings(&state, &headers, "workspace", &workspace_slug, "note", &settings_slug, payload).await
|
||||
save_editor_settings(
|
||||
&state,
|
||||
&headers,
|
||||
"workspace",
|
||||
&workspace_slug,
|
||||
"note",
|
||||
&settings_slug,
|
||||
payload,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn history(
|
||||
@@ -840,4 +919,3 @@ async fn unique_note_slug(
|
||||
}
|
||||
Err(ApiError::internal("Failed to create a unique address"))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user