settings: add base url, WIP flash system
This commit is contained in:
parent
f2bea92272
commit
c670201b86
18 changed files with 190 additions and 68 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -565,6 +565,7 @@ dependencies = [
|
||||||
"rocket_db_pools",
|
"rocket_db_pools",
|
||||||
"rocket_dyn_templates",
|
"rocket_dyn_templates",
|
||||||
"settings",
|
"settings",
|
||||||
|
"url",
|
||||||
"users",
|
"users",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2071,6 +2072,7 @@ dependencies = [
|
||||||
"database",
|
"database",
|
||||||
"id",
|
"id",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,5 @@ members = [
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
chrono = "0.4.23"
|
chrono = "0.4.23"
|
||||||
sqlx = "0.5.13"
|
sqlx = "0.5.13"
|
||||||
|
url = "2.3.1"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
alter table settings
|
||||||
|
drop column url;
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
alter table settings
|
||||||
|
add column url TEXT;
|
||||||
|
|
@ -2,7 +2,8 @@ select id,
|
||||||
created_at as "created_at: DateTime<Utc>",
|
created_at as "created_at: DateTime<Utc>",
|
||||||
updated_at as "updated_at: DateTime<Utc>",
|
updated_at as "updated_at: DateTime<Utc>",
|
||||||
business_name,
|
business_name,
|
||||||
business_logo
|
business_logo,
|
||||||
|
url
|
||||||
|
|
||||||
from settings
|
from settings
|
||||||
|
|
||||||
|
|
|
||||||
5
crates/database/queries/settings/set_url.sql
Normal file
5
crates/database/queries/settings/set_url.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
update settings
|
||||||
|
|
||||||
|
set url = ?
|
||||||
|
|
||||||
|
where id is 0
|
||||||
|
|
@ -40,6 +40,64 @@
|
||||||
},
|
},
|
||||||
"query": "insert or ignore into settings(id)\nvalues (0);"
|
"query": "insert or ignore into settings(id)\nvalues (0);"
|
||||||
},
|
},
|
||||||
|
"64cf880633d3ee5c18f6e7c2a865470442f1ba4b1019806a580ec384329dc32e": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "created_at: DateTime<Utc>",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "updated_at: DateTime<Utc>",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "business_name",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "business_logo",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Blob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "url",
|
||||||
|
"ordinal": 5,
|
||||||
|
"type_info": "Text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "select id,\n created_at as \"created_at: DateTime<Utc>\",\n updated_at as \"updated_at: DateTime<Utc>\",\n business_name,\n business_logo,\n url\n\nfrom settings\n\nwhere id is 0\n"
|
||||||
|
},
|
||||||
|
"87906834faa6f185aee0e4d893b9754908b1c173e9dce383663d723891a89cd1": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "update settings\n\nset url = ?\n\nwhere id is 0\n"
|
||||||
|
},
|
||||||
"aae93a39c5a9f46235b5ef871b45ba76d7efa1677bfe8291a62b8cbf9cd9e0d5": {
|
"aae93a39c5a9f46235b5ef871b45ba76d7efa1677bfe8291a62b8cbf9cd9e0d5": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
|
|
@ -127,47 +185,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"query": "select u.id,\n u.created_at as \"created_at: DateTime<Utc>\",\n u.updated_at as \"updated_at: DateTime<Utc>\",\n u.is_admin as \"is_admin: bool\",\n u.username,\n u.name,\n u.email,\n u.password,\n u.password_recover,\n u.paper_key,\n u.is_archived as \"is_archived: bool\"\nfrom users u\n\n inner join settings s on u.id = s.first_admin\n\nwhere u.is_admin is 1\n and u.is_archived is 0\n and u.id is s.first_admin\n\nlimit 1"
|
"query": "select u.id,\n u.created_at as \"created_at: DateTime<Utc>\",\n u.updated_at as \"updated_at: DateTime<Utc>\",\n u.is_admin as \"is_admin: bool\",\n u.username,\n u.name,\n u.email,\n u.password,\n u.password_recover,\n u.paper_key,\n u.is_archived as \"is_archived: bool\"\nfrom users u\n\n inner join settings s on u.id = s.first_admin\n\nwhere u.is_admin is 1\n and u.is_archived is 0\n and u.id is s.first_admin\n\nlimit 1"
|
||||||
},
|
|
||||||
"cc69514c4d9457462e634eb58cbfc82b454197c5cb7f4a451954eb5a421afc3b": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "id",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Int64"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "created_at: DateTime<Utc>",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "updated_at: DateTime<Utc>",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "business_name",
|
|
||||||
"ordinal": 3,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "business_logo",
|
|
||||||
"ordinal": 4,
|
|
||||||
"type_info": "Blob"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "select id,\n created_at as \"created_at: DateTime<Utc>\",\n updated_at as \"updated_at: DateTime<Utc>\",\n business_name,\n business_logo\n\nfrom settings\n\nwhere id is 0\n"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -10,6 +10,7 @@ pub struct Settings {
|
||||||
pub updated_at: DateTime<Utc>,
|
pub updated_at: DateTime<Utc>,
|
||||||
pub business_name: Option<String>,
|
pub business_name: Option<String>,
|
||||||
pub business_logo: Option<Vec<u8>>,
|
pub business_logo: Option<Vec<u8>>,
|
||||||
|
pub url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
|
|
@ -67,4 +68,13 @@ impl Settings {
|
||||||
|
|
||||||
Ok((query.rows_affected() == 1).then_some(()))
|
Ok((query.rows_affected() == 1).then_some(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn set_url(conn: impl SqliteExecutor<'_>, url: &str) -> Result<Option<()>, Error> {
|
||||||
|
let query: SqliteQueryResult = sqlx::query_file!("queries/settings/set_url.sql", url)
|
||||||
|
.execute(conn)
|
||||||
|
.await
|
||||||
|
.map_err(handle_error)?;
|
||||||
|
|
||||||
|
Ok((query.rows_affected() == 1).then_some(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ rocket_db_pools = { version = "0.1.0-rc.2", features = ["sqlx_sqlite"] }
|
||||||
rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["tera"] }
|
rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["tera"] }
|
||||||
infer = { version = "0.12.0", default-features = false }
|
infer = { version = "0.12.0", default-features = false }
|
||||||
erased-serde = "0.3"
|
erased-serde = "0.3"
|
||||||
|
url = { workspace = true }
|
||||||
|
|
||||||
# local crates
|
# local crates
|
||||||
database_pool = { path = "../database_pool" }
|
database_pool = { path = "../database_pool" }
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
mod content;
|
mod content;
|
||||||
|
mod flash;
|
||||||
mod responder;
|
mod responder;
|
||||||
mod template;
|
mod template;
|
||||||
|
|
||||||
use self::content::*;
|
use self::content::*;
|
||||||
use erased_serde::Serialize;
|
use erased_serde::Serialize;
|
||||||
|
|
||||||
|
pub use flash::FlashKind;
|
||||||
|
|
||||||
pub enum Page {
|
pub enum Page {
|
||||||
Error(Error),
|
Error(Error),
|
||||||
Setup,
|
Setup,
|
||||||
|
|
|
||||||
29
crates/ezidam/src/page/flash.rs
Normal file
29
crates/ezidam/src/page/flash.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
pub enum FlashKind {
|
||||||
|
Success,
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Danger,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for FlashKind {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{}",
|
||||||
|
match self {
|
||||||
|
FlashKind::Success => "success",
|
||||||
|
FlashKind::Info => "info",
|
||||||
|
FlashKind::Warning => "warning",
|
||||||
|
FlashKind::Danger => "danger",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<String> for FlashKind {
|
||||||
|
fn into(self) -> String {
|
||||||
|
self.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use super::Page;
|
use super::Page;
|
||||||
|
use rocket::request::FlashMessage;
|
||||||
use rocket::serde::Serialize;
|
use rocket::serde::Serialize;
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
|
|
@ -7,20 +8,32 @@ use rocket_dyn_templates::Template;
|
||||||
struct TemplateContent<S: Serialize> {
|
struct TemplateContent<S: Serialize> {
|
||||||
title: &'static str,
|
title: &'static str,
|
||||||
version: &'static str,
|
version: &'static str,
|
||||||
|
flash: Option<(String, String)>,
|
||||||
|
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
content: S,
|
content: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render(p: Page, flash: Option<(String, String)>) -> Template {
|
||||||
|
Template::render(
|
||||||
|
p.template_name(),
|
||||||
|
TemplateContent {
|
||||||
|
title: p.page_title(),
|
||||||
|
version: env!("CARGO_PKG_VERSION"),
|
||||||
|
flash,
|
||||||
|
content: p.content(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Page> for Template {
|
impl From<Page> for Template {
|
||||||
fn from(p: Page) -> Self {
|
fn from(p: Page) -> Self {
|
||||||
Self::render(
|
render(p, None)
|
||||||
p.template_name(),
|
}
|
||||||
TemplateContent {
|
}
|
||||||
title: p.page_title(),
|
|
||||||
version: env!("CARGO_PKG_VERSION"),
|
impl Page {
|
||||||
content: p.content(),
|
pub fn with_flash(self, flash: FlashMessage) -> Template {
|
||||||
},
|
render(self, Some(flash.into_inner()))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,19 @@ pub(self) mod prelude {
|
||||||
pub use crate::error::Error;
|
pub use crate::error::Error;
|
||||||
pub use crate::file_from_bytes::FileFromBytes;
|
pub use crate::file_from_bytes::FileFromBytes;
|
||||||
pub use crate::guards::*;
|
pub use crate::guards::*;
|
||||||
pub use crate::page::Page;
|
pub use crate::page::{FlashKind, Page};
|
||||||
pub use hash::Password;
|
pub use hash::Password;
|
||||||
pub use id::UserID;
|
pub use id::UserID;
|
||||||
pub use rocket::form::Form;
|
pub use rocket::form::Form;
|
||||||
|
pub use rocket::request::FlashMessage;
|
||||||
|
pub use rocket::response::Flash;
|
||||||
pub use rocket::response::Redirect;
|
pub use rocket::response::Redirect;
|
||||||
pub use rocket::tokio::task;
|
pub use rocket::tokio::task;
|
||||||
pub use rocket::FromForm;
|
pub use rocket::FromForm;
|
||||||
pub use rocket::{routes, uri, Either, Route};
|
pub use rocket::{routes, uri, Either, Route};
|
||||||
pub use rocket_db_pools::sqlx::Acquire;
|
pub use rocket_db_pools::sqlx::Acquire;
|
||||||
pub use rocket_db_pools::Connection;
|
pub use rocket_db_pools::Connection;
|
||||||
|
pub use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use super::prelude::*;
|
use super::prelude::*;
|
||||||
use rocket::{get, post};
|
use rocket::{get, post};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
use url::Url;
|
||||||
use users::User;
|
use users::User;
|
||||||
|
|
||||||
pub fn routes() -> Vec<Route> {
|
pub fn routes() -> Vec<Route> {
|
||||||
|
|
@ -13,14 +14,18 @@ async fn setup_completed(_setup: CompletedSetup) -> Redirect {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/", rank = 2)]
|
#[get("/", rank = 2)]
|
||||||
async fn setup() -> Page {
|
async fn setup(flash: Option<FlashMessage<'_>>) -> Template {
|
||||||
Page::Setup
|
// TODO: show flash on html page
|
||||||
|
flash
|
||||||
|
.map(|flash| Page::with_flash(Page::Setup, flash))
|
||||||
|
.unwrap_or_else(|| Page::Setup.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, FromForm)]
|
#[derive(Debug, FromForm)]
|
||||||
pub struct CreateFirstAccount<'r> {
|
pub struct CreateFirstAccount<'r> {
|
||||||
pub username: &'r str,
|
pub username: &'r str,
|
||||||
pub password: &'r str,
|
pub password: &'r str,
|
||||||
|
pub url: &'r str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/", data = "<form>")]
|
#[post("/", data = "<form>")]
|
||||||
|
|
@ -28,9 +33,18 @@ async fn create_first_account(
|
||||||
form: Form<CreateFirstAccount<'_>>,
|
form: Form<CreateFirstAccount<'_>>,
|
||||||
_setup: NeedSetup,
|
_setup: NeedSetup,
|
||||||
mut db: Connection<Database>,
|
mut db: Connection<Database>,
|
||||||
) -> Result<Redirect> {
|
) -> Result<Either<Redirect, Flash<Redirect>>> {
|
||||||
let form = form.into_inner();
|
let form = form.into_inner();
|
||||||
|
|
||||||
|
// Parse url
|
||||||
|
return Ok(Either::Right(Flash::new(
|
||||||
|
Redirect::to(uri!(self::setup)),
|
||||||
|
FlashKind::Danger,
|
||||||
|
"Failed to parse url".to_string(),
|
||||||
|
)));
|
||||||
|
|
||||||
|
let url = Url::parse(form.url).unwrap();
|
||||||
|
|
||||||
// Generate UserID
|
// Generate UserID
|
||||||
let user_id = task::spawn_blocking(UserID::default).await?;
|
let user_id = task::spawn_blocking(UserID::default).await?;
|
||||||
|
|
||||||
|
|
@ -40,7 +54,7 @@ async fn create_first_account(
|
||||||
|
|
||||||
let mut transaction = db.begin().await?;
|
let mut transaction = db.begin().await?;
|
||||||
|
|
||||||
// Insert in database
|
// Insert user in database
|
||||||
User::insert(
|
User::insert(
|
||||||
&mut transaction,
|
&mut transaction,
|
||||||
&user_id,
|
&user_id,
|
||||||
|
|
@ -53,11 +67,14 @@ async fn create_first_account(
|
||||||
// Store UserID in settings
|
// Store UserID in settings
|
||||||
Settings::set_first_admin(&mut transaction, &user_id).await?;
|
Settings::set_first_admin(&mut transaction, &user_id).await?;
|
||||||
|
|
||||||
|
// Store URL in settings
|
||||||
|
Settings::set_url(&mut transaction, &url).await?;
|
||||||
|
|
||||||
transaction.commit().await?;
|
transaction.commit().await?;
|
||||||
|
|
||||||
// TODO: login with openid/oauth
|
// TODO: login with openid/oauth
|
||||||
|
|
||||||
Ok(Redirect::to(uri!("/")))
|
Ok(Either::Left(Redirect::to(uri!("/"))))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
@ -77,10 +94,9 @@ mod test {
|
||||||
let create_account = client
|
let create_account = client
|
||||||
.post(uri!("/setup"))
|
.post(uri!("/setup"))
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
.body(r#"username=phil&password=password"#)
|
.body(r#"username=phil&password=password&url=https://example.com"#)
|
||||||
.dispatch();
|
.dispatch();
|
||||||
assert_ne!(create_account.status(), Status::UnprocessableEntity);
|
assert_eq!(create_account.status(), Status::SeeOther);
|
||||||
assert_ne!(create_account.status(), Status::InternalServerError);
|
|
||||||
|
|
||||||
// Make request again, make sure its not OK
|
// Make request again, make sure its not OK
|
||||||
let setup_page_after_creation = client.get(uri!("/setup")).dispatch();
|
let setup_page_after_creation = client.get(uri!("/setup")).dispatch();
|
||||||
|
|
|
||||||
|
|
@ -16,27 +16,35 @@
|
||||||
<h1 class="">Welcome to Ezidam!</h1>
|
<h1 class="">Welcome to Ezidam!</h1>
|
||||||
<p class="text-muted">Initial setup</p>
|
<p class="text-muted">Initial setup</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- First admin account -->
|
||||||
<div class="hr-text hr-text-center hr-text-spaceless">first admin account</div>
|
<div class="hr-text hr-text-center hr-text-spaceless">first admin account</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label required" for="username">Username</label>
|
<label class="form-label required" for="username">Username</label>
|
||||||
<input name="username" id="username" type="text" class="form-control" required>
|
<input name="username" id="username" type="text" placeholder="Enter a username" class="form-control" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label required" for="password">Password</label>
|
<label class="form-label required" for="password">Password</label>
|
||||||
<div class="input-group input-group-flat">
|
<div class="input-group input-group-flat">
|
||||||
<input name="password" id="password" type="password" class="form-control" autocomplete="off" required>
|
<input name="password" id="password" type="password" placeholder="Enter password" class="form-control" autocomplete="off" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Settings -->
|
||||||
|
<div class="hr-text hr-text-center hr-text-spaceless">settings</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label required" for="url">Base URL</label>
|
||||||
|
<input name="url" id="url" type="url" placeholder="https://example.com" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row align-items-center mt-3">
|
<div class="row align-items-center mt-3">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="btn-list justify-content-end">
|
<div class="btn-list justify-content-end">
|
||||||
<button type="submit" class="btn btn-primary">Create account</button>
|
<button type="submit" class="btn btn-primary">Finish setup</button>
|
||||||
<!-- <a href="#" class="btn btn-primary">-->
|
|
||||||
<!-- Create account-->
|
|
||||||
<!-- </a>-->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,5 @@ edition = "2021"
|
||||||
database = { path = "../database" }
|
database = { path = "../database" }
|
||||||
id = { path = "../id" }
|
id = { path = "../id" }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
|
url = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use crate::Settings;
|
||||||
use database::sqlx::SqliteExecutor;
|
use database::sqlx::SqliteExecutor;
|
||||||
use database::Settings as DatabaseSettings;
|
use database::Settings as DatabaseSettings;
|
||||||
use id::UserID;
|
use id::UserID;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
const DEFAULT_BUSINESS_NAME: &str = "ezidam";
|
const DEFAULT_BUSINESS_NAME: &str = "ezidam";
|
||||||
pub const DEFAULT_BUSINESS_LOGO: &[u8] = include_bytes!("../../../logo/ezidam.png");
|
pub const DEFAULT_BUSINESS_LOGO: &[u8] = include_bytes!("../../../logo/ezidam.png");
|
||||||
|
|
@ -18,6 +19,7 @@ impl From<DatabaseSettings> for Settings {
|
||||||
business_logo: db
|
business_logo: db
|
||||||
.business_logo
|
.business_logo
|
||||||
.unwrap_or_else(|| DEFAULT_BUSINESS_LOGO.to_vec()),
|
.unwrap_or_else(|| DEFAULT_BUSINESS_LOGO.to_vec()),
|
||||||
|
url: db.url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -55,4 +57,10 @@ impl Settings {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn set_url(conn: impl SqliteExecutor<'_>, url: &Url) -> Result<(), Error> {
|
||||||
|
DatabaseSettings::set_url(conn, url.as_str()).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ pub struct Settings {
|
||||||
updated_at: DateTime<Utc>,
|
updated_at: DateTime<Utc>,
|
||||||
business_name: String,
|
business_name: String,
|
||||||
business_logo: Vec<u8>,
|
business_logo: Vec<u8>,
|
||||||
|
url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue