added consent, fixed templating

This commit is contained in:
Kyattsukuro 2025-09-10 20:18:19 +02:00
parent 70c3515d2e
commit 1914993d7b
19 changed files with 305 additions and 172 deletions

125
Cargo.lock generated
View File

@ -227,6 +227,7 @@ dependencies = [
"clap",
"custom_error",
"diesel",
"diesel-derive-enum",
"enum_dispatch",
"log",
"reqwest",
@ -462,7 +463,7 @@ version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
dependencies = [
"heck",
"heck 0.5.0",
"proc-macro2",
"quote",
"syn",
@ -753,6 +754,18 @@ dependencies = [
"time",
]
[[package]]
name = "diesel-derive-enum"
version = "3.0.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50a8c082045d01debc8589f8a0db9f2855a37c99c9b031325c856b5b98e1625f"
dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "diesel_derives"
version = "2.2.7"
@ -806,7 +819,7 @@ checksum = "139ae9aca7527f85f26dd76483eb38533fd84bd571065da1739656ef71c5ff5b"
dependencies = [
"darling",
"either",
"heck",
"heck 0.5.0",
"proc-macro2",
"quote",
"syn",
@ -1233,26 +1246,18 @@ dependencies = [
"tracing",
]
[[package]]
name = "handlebars"
version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225"
dependencies = [
"log",
"pest",
"pest_derive",
"serde",
"serde_json",
"thiserror 1.0.69",
]
[[package]]
name = "hashbrown"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "heck"
version = "0.5.0"
@ -1872,12 +1877,32 @@ version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "memo-map"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38d1115007560874e373613744c6fba374c17688327a71c1476d1a5954cc857b"
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "minijinja"
version = "2.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9f264d75233323f4b7d2f03aefe8a990690cdebfbfe26ea86bcbaec5e9ac990"
dependencies = [
"memo-map",
"percent-encoding",
"self_cell",
"serde",
"serde_json",
"v_htmlescape",
]
[[package]]
name = "miniz_oxide"
version = "0.8.9"
@ -2283,50 +2308,6 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323"
dependencies = [
"memchr",
"thiserror 2.0.12",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5"
dependencies = [
"pest",
"sha2",
]
[[package]]
name = "pin-project-lite"
version = "0.2.16"
@ -2699,11 +2680,11 @@ dependencies = [
[[package]]
name = "rocket_dyn_templates"
version = "0.1.0"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04bfc006e547e4f72b760ab861f5943b688aed8a82c4977b5500c98f5d17dbfa"
checksum = "5bbab919c9e67df3f7ac6624a32ef897df4cd61c0969f4d66f3ced0534660d7a"
dependencies = [
"handlebars",
"minijinja",
"normpath",
"notify",
"rocket",
@ -3030,6 +3011,12 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "689224d06523904ebcc9b482c6a3f4f7fb396096645c4cd10c0d2ff7371a34d3"
[[package]]
name = "self_cell"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"
[[package]]
name = "semver"
version = "1.0.26"
@ -3654,12 +3641,6 @@ dependencies = [
"serde",
]
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "uncased"
version = "0.9.10"
@ -3721,6 +3702,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "v_htmlescape"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c"
[[package]]
name = "valuable"
version = "0.1.1"

View File

@ -2,7 +2,6 @@
name = "auto-decrypt"
version = "0.1.0"
edition = "2024"
template_dir = "src/api/templates"
[dependencies]
async-trait = "0.1.88"
@ -17,7 +16,5 @@ rocket = "0.5.1"
url = "2"
custom_error = "1.9.2"
enum_dispatch = "0.3.13"
[dependencies.rocket_dyn_templates]
version = "0.1.0"
features = ["minijinja"]
rocket_dyn_templates = { version = "0.2.0", features = ["minijinja"]}
diesel-derive-enum = { version = "3.0.0-beta.1", features = ["sqlite"] }

View File

@ -1,6 +1,7 @@
-- Your SQL goes here
CREATE TABLE providers_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
service_name TEXT NOT NULL,
request_time BIGINT UNSIGNED NOT NULL,
auth_methode TEXT NOT NULL,
@ -12,7 +13,7 @@ CREATE TABLE providers_records (
);
CREATE TABLE beggars_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
request_time BIGINT UNSIGNED NOT NULL,
service_name TEXT NOT NULL,
http_result INTEGER UNSIGNED NOT NULL,

View File

@ -1,12 +1,93 @@
use log::Level;
use rocket_dyn_templates::{Template, context};
use crate::orm::DbConn;
use rocket::State;
use crate::{api::helpers::{execute_action, find_provider_by_name}, app_config::CONFIG, orm::{DbConn, types::RecordStates}};
use rocket::{State, form::Form};
use serde::Serialize;
use crate::orm::types::AuthMethod;
use crate::orm::structures::ProviderRecord;
// Helper function for rendering
fn render_consent(record: &ProviderRecord, msg: Option<UserMessage>) -> Template {
Template::render("consent", context! {
service: record,
message: msg
})
}
#[get("/<consent_id>", rank = 1)]
pub(crate) fn consent(consent_id: i32, db_conn: &State<DbConn>) -> Template {
pub(crate) fn consent(consent_id: i32, db_conn: &State<DbConn>) -> Result<Template, String> {
let record = db_conn.get_record(consent_id);
if record.is_none() {
return Err("Record not found".to_string());
}
Ok(Template::render("consent", context! {
service: record.unwrap(),
}))
}
#[derive(FromForm)]
struct ConsentInput {
key: Option<String>,
rejected: bool,
}
#[derive(serde::Serialize)]
enum MessageType {
Warn,
Danger,
Success
}
#[derive(serde::Serialize)]
struct UserMessage {
level: MessageType,
message: String
}
#[post("/<consent_id>", data = "<consent_input>", rank = 1)]
pub(crate) async fn consent_post<'a>(
consent_id: i32,
consent_input: Form<ConsentInput>,
db_conn: &State<DbConn>,
) -> Result<Template, String> {
let mut record = db_conn
.get_record(consent_id)
.ok_or("Record not found".to_string())?;
// Determine acceptance
let accept = match record.auth_methode {
AuthMethod::Password => Some(!consent_input.rejected), // TODO: Add decryption check
_ => Some(!consent_input.rejected),
};
if accept != Some(true) {
let state = if accept == Some(false) { RecordStates::Rejected } else { RecordStates::Failed };
record = db_conn.update_provider_state(record.id, state);
let msg = if accept == Some(false) {
"The unlock request was rejected."
} else {
"The unlock request failed, wrong credentials!"
};
return Ok(render_consent(&record, Some(UserMessage {
level: MessageType::Danger,
message: msg.to_string()
})));
}
let (_, provider) = find_provider_by_name(&record.service_name)
.ok_or("Service has been deleted.".to_string())?;
Template::render("index", context! {
service: db_conn.get_record(consent_id)
})
}
let (new_state, message) = match execute_action(provider, consent_input.key.as_deref()).await {
Ok(msg) => (RecordStates::Accepted, UserMessage { level: MessageType::Success, message: msg }),
Err(err) => (RecordStates::Failed, UserMessage { level: MessageType::Danger, message: err.to_string() }),
};
record = db_conn.update_provider_state(record.id, new_state);
Ok(render_consent(&record, Some(message)))
}

View File

@ -1,7 +1,6 @@
use clap::Error;
use rocket::form::Strict;
use rocket::request::{Outcome, Request, FromRequest};
use url::form_urlencoded;
use crate::app_config::CONFIG;
use crate::orm::DbConn;
use crate::api::State;
@ -9,20 +8,9 @@ use rocket::http::uri::Query;
use crate::services::providers::Providers;
use super::HttpResult;
use super::helpers::{get_query_value, find_provider_by_name};
fn get_query_value(query: &Option<Query>, query_key: &str) -> Option<String> {
if let Some(query) = query {
// Parse the query string manually
for (key, value) in form_urlencoded::parse(query.as_bytes()) {
if key == query_key {
return Some(value.to_string());
}
}
}
None
}
pub(super) struct APIProviderRequest<'r> {
pub share: &'r Providers,
@ -44,11 +32,8 @@ impl<'r> FromRequest<'r> for APIProviderRequest<'r> {
return Outcome::Error(HttpResult::ShareNotFound("No share name provided.".to_string()).into());
}
if let Some(service) = CONFIG
.wait()
.providers
.iter()
.find(|(name, service)| *name == share_name && service.access_key_hash == access_key)
if let Some(service) = find_provider_by_name(share_name)
.filter(|(_, service)| {service.access_key_hash == access_key})
{
Outcome::Success(APIProviderRequest { share: service.1, name: service.0 })
} else {

52
src/api/helpers.rs Normal file
View File

@ -0,0 +1,52 @@
// 1.Find provider by name
// 2.execute provider
use url::form_urlencoded;
use rocket::http::uri::Query;
use core::time;
use std::time::SystemTime;
use super::guards::APIProviderRequest;
use crate::api::guards;
use crate::errors::AutoDecryptError;
use crate::main;
use crate::orm::structures::{BaseProviderRecord};
use crate::orm::types::{AuthMethod, RecordStates};
use crate::services::providers::{ConsentMethode, ProviderAction, Providers, ActionType};
use crate::app_config::CONFIG;
pub(super) fn get_query_value(query: &Option<Query>, query_key: &str) -> Option<String> {
if let Some(query) = query {
// Parse the query string manually
for (key, value) in form_urlencoded::parse(query.as_bytes()) {
if key == query_key {
return Some(value.to_string());
}
}
}
None
}
pub(super) async fn execute_action(action: &Providers, key: Option<&str>) -> Result<String, AutoDecryptError> {
let exec_action = match &action.execution_action {
ActionType::ForigneAction(forigne_action) => {
&forigne_action.to_executable_action(key)? as &dyn ProviderAction
},
_ => &action.execution_action as &dyn ProviderAction,
};
exec_action.execute().await
}
pub(super) fn find_provider_by_name(name: &str) -> Option<(&String, &Providers)> {
CONFIG
.wait()
.providers
.iter()
.find(|(serv_name, _)| *serv_name == name)
}

View File

@ -1,14 +1,18 @@
mod guards;
mod request;
mod consent;
mod helpers;
use crate::app_config::CONFIG;
use crate::orm::DbConn;
use crate::api::consent::{consent as consent_template, consent_post};
// Alternativly iport rocket manually: use rocket::get;
use rocket::{fs::FileServer, Config};
use rocket::response::Redirect;
use rocket::fs::NamedFile;
use rocket::State;
use rocket_dyn_templates::Template;
use serde::Deserialize;
use core::marker::{Send, Sync};
use std::net::IpAddr;
@ -63,9 +67,10 @@ pub(crate) async fn start_api() -> () {
let _ = rocket::build()
.manage(DbConn::establish_connection(&CONFIG.wait().db_file))
.attach(Template::fairing())
.mount("/", routes![index])
.mount("/request", routes![request::request_handler])
.mount("/consent", routes![request::consent])
.mount("/consent", routes![consent_template, consent_post])
.register("/", catchers![default])
.configure(rocket_config)
.launch()

View File

@ -1,9 +1,12 @@
use core::time;
use std::time::SystemTime;
use super::guards::APIProviderRequest;
use crate::api::guards;
use crate::errors::AutoDecryptError;
use crate::main;
use crate::orm::structures::{ProviderRecord};
use crate::orm::structures::{BaseProviderRecord};
use crate::orm::types::{AuthMethod, RecordStates};
use crate::services::providers::{ConsentMethode, ProviderAction, Providers, ActionType};
use crate::app_config::CONFIG;
@ -13,18 +16,8 @@ use rocket::get;
use rocket::http::Status;
use rocket::State;
use super::HttpResult;
use super::helpers::execute_action;
async fn execute_action(action: &Providers, key: Option<&str>) -> Result<String, AutoDecryptError> {
let exec_action = match &action.execution_action {
ActionType::ForigneAction(forigne_action) => {
&forigne_action.to_executable_action(key)? as &dyn ProviderAction
},
_ => &action.execution_action as &dyn ProviderAction,
};
exec_action.execute().await
}
#[get("/<_>", rank = 1)]
@ -58,13 +51,16 @@ pub(super) async fn request_handler(guard: Result<APIProviderRequest<'_>, HttpRe
_ => RecordStates::Rejected,
};
db_conn.add_provider_record(&ProviderRecord {
db_conn.add_provider_record(&BaseProviderRecord {
service_name: guard.name.to_string(),
expires_at: expires_at,
auth_methode: auth_methode,
has_notifyed: false,
state: record_state,
awnsered_by: None,
awnsered_at: None,
request_time: SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as i64,
});
return result.into();

View File

@ -1,22 +0,0 @@
{% extends "base.html" %}
{% set _inputStates = ["Pending"] %}
<h1>Consent {{service.name}}</h1>
<h3>Request Information:</h3>
<ul>
<li>Service name: {{service.name}}</li>
<li>Requested at: {{service.reqest_time}}</li>
<li>Auth methode: {{service.expires_at}}</li>
<li>Service State: {{service.state}}</li>
</ul>
{% if message %}
{% include "message.html.j2" with message %}
{% endif %}
{% if service.state not in _inputStates %}
{% include "_consent_form.html.j2" %}
{% else %}
{% include "_consent_noinput.html.j2" %}
{% endif %}

View File

@ -1,7 +1,11 @@
use std::time;
use diesel::RunQueryDsl;
use diesel::QueryDsl;
use diesel::ExpressionMethods;
use std::time::SystemTime;
use super::DbConn;
use super::structures::*;
use crate::orm::schema::{providers_records, beggars_records};
@ -9,19 +13,25 @@ use crate::orm::schema::{providers_records, beggars_records};
use super::types::RecordStates;
impl DbConn {
pub(crate) fn add_provider_record(&self, record: &ProviderRecord) {
pub(crate) fn add_provider_record(&self, record: &BaseProviderRecord) {
let conn = &mut *self.0.lock().unwrap();
diesel::insert_into(providers_records::table)
.values(record)
.execute(conn)
.expect("Error saving new service record");
}
pub(crate) fn update_provider_state(&self, id: i32, new_state: RecordStates) {
pub(crate) fn update_provider_state(&self, id: i32, new_state: RecordStates) -> ProviderRecord {
let conn = &mut *self.0.lock().unwrap();
let now_unix = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as i64;
diesel::update(providers_records::table.filter(providers_records::dsl::id.eq(id)))
.set(providers_records::state.eq(new_state.to_string()))
.set((
providers_records::state.eq(new_state.to_string()),
providers_records::awnsered_at.eq(Some(now_unix)),
))
.execute(conn)
.expect("Error updating service record state");
self.get_record(id).unwrap()
}
pub(crate) fn add_beggars_record(&self, record: &BeggarsRecord) {
@ -32,8 +42,12 @@ impl DbConn {
.expect("Error saving new beggars record");
}
pub(crate) fn get_record(&self, id: i32) -> Option<RecordStates> {
let conn = &mut *self.0.lock().unwrap();
record_states.find(id).get_result::<RecordState>(conn)
}
pub(crate) fn get_record(&self, id: i32) -> Option<ProviderRecord> {
use crate::orm::handler::providers_records::dsl::providers_records;
let conn = &mut *self.0.lock().unwrap();
let a = providers_records.find(id).get_result(conn).ok();
a
}
}

View File

@ -2,7 +2,7 @@
diesel::table! {
beggars_records (id) {
id -> Nullable<Integer>,
id -> Integer,
request_time -> BigInt,
service_name -> Text,
http_result -> Integer,
@ -13,7 +13,7 @@ diesel::table! {
diesel::table! {
providers_records (id) {
id -> Nullable<Integer>,
id -> Integer,
service_name -> Text,
request_time -> BigInt,
auth_methode -> Text,

View File

@ -1,27 +1,36 @@
use clap::builder::Str;
use diesel::{
deserialize::FromSql,
serialize::{Output, ToSql},
sql_types::Text,
Queryable,
Selectable,
Insertable,
sqlite::{Sqlite, SqliteValue},
AsExpression, FromSqlRow,
AsExpression, FromSqlRow, Insertable, Queryable, Selectable, deserialize::FromSql, query_builder::QueryId, serialize::{Output, ToSql}, sql_types::Text, sqlite::{Sqlite, SqliteValue}
};
use serde::Serialize;
use std::fmt;
use super::types::{RecordStates, AuthMethod};
#[derive(Debug)]
#[derive(Queryable, Selectable, Insertable)]
#[derive(Insertable, Serialize)]
#[diesel(table_name = super::schema::providers_records)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub(crate) struct ProviderRecord{
pub(crate) struct BaseProviderRecord {
pub(crate) service_name: String,
pub(crate) expires_at: Option<i64>, // Unix timestamp
pub(crate) request_time: i64,
pub(crate) auth_methode: AuthMethod,
pub(crate) expires_at: Option<i64>,
pub(crate) has_notifyed: bool,
pub(crate) state: RecordStates,
pub(crate) awnsered_at: Option<i64>,
pub(crate) awnsered_by: Option<String>,
}
#[derive(Queryable, Selectable, Serialize)]
#[diesel(table_name = super::schema::providers_records)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub(crate) struct ProviderRecord {
pub(crate) id: i32,
pub(crate) service_name: String,
pub(crate) request_time: i64,
pub(crate) auth_methode: AuthMethod,
pub(crate) expires_at: Option<i64>,
pub(crate) has_notifyed: bool,
pub(crate) state: RecordStates,
pub(crate) awnsered_at: Option<i64>,
pub(crate) awnsered_by: Option<String>,
}

View File

@ -9,16 +9,21 @@ use diesel::{
sqlite::{Sqlite, SqliteValue},
AsExpression, FromSqlRow,
};
use serde::Serialize;
use std::fmt;
use diesel::sql_types::BigInt;
use crate::services::providers::ConsentMethode;
#[derive(FromSqlRow, Debug, AsExpression)]
#[derive(FromSqlRow, Debug, AsExpression, Serialize)]
#[diesel(sql_type = Text)]
pub(crate) enum RecordStates {
Pending,
Accepted,
Rejected,
Expired,
Failed
}
impl fmt::Display for RecordStates {
@ -28,6 +33,7 @@ impl fmt::Display for RecordStates {
RecordStates::Accepted => write!(f, "Accepted"),
RecordStates::Rejected => write!(f, "Rejected"),
RecordStates::Expired => write!(f, "Expired"),
RecordStates::Failed => write!(f, "Failed")
}
}
}
@ -41,6 +47,7 @@ impl TryFrom<&str> for RecordStates {
"Accepted" => Ok(RecordStates::Accepted),
"Rejected" => Ok(RecordStates::Rejected),
"Expired" => Ok(RecordStates::Expired),
"Failed" => Ok(RecordStates::Failed),
_ => Err(format!("Unknown state: {}", value)),
}
}
@ -61,7 +68,7 @@ impl ToSql<Text, Sqlite> for RecordStates {
}
#[derive(FromSqlRow, Debug, AsExpression)]
#[derive(FromSqlRow, Debug, AsExpression, Serialize)]
#[diesel(sql_type = Text)]
pub(crate) enum AuthMethod {
None,
@ -105,7 +112,6 @@ impl ToSql<Text, Sqlite> for AuthMethod {
}
}
use crate::services::providers::ConsentMethode;
impl From<&ConsentMethode> for AuthMethod {
fn from(value: &ConsentMethode) -> Self {

View File

@ -1,15 +1,15 @@
{% if service.auth_methode == "Password" %}
<p>A passkey is required to decrypt the service.</p>
<form action="/consent" method="POST">
<form method="POST">
<input type="password" name="key" placeholder="Key"/>
<input type="submit" value="reject">Reject</input>
<input type="submit" value="accept">Accept</input>
<input type="submit" name="rejected" value="true">Reject</input>
<input type="submit" name="rejected" value="false">Accept</input>
</form>
{% elif service.auth_methode == "Confirmation" %}
<form action="/consent" method="POST">
<input type="submit" value="reject">Reject</input>
<input type="submit" value="accept">Accept</input>
<form method="POST">
<input type="submit" name="rejected" value="true">Reject</input>
<input type="submit" name="rejected" value="false">Accept</input>
</form>
{% else %}
<p>This request dose not require any type of consent.

View File

@ -5,9 +5,9 @@
} %}
{% set icon = {
"warn": "⚠️",
"danger": "❌",
"success":"✅"
"Warn": "⚠️",
"Danger": "❌",
"Success":"✅"
} %}
<div class="rounded-md border p-4 flex items-center space-x-2 {{ colors.get(type, colors['warn']) }}">

View File

@ -5,7 +5,6 @@
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>{% block title %}{% endblock %}</title>
{% block styles %}
<link rel="stylesheet" href="/static/css/main.css">
{% endblock %}
</head>
<body>

23
templates/consent.html.j2 Normal file
View File

@ -0,0 +1,23 @@
{% extends "base" %}
{% block content %}
{% set _inputStates = ["Pending"] %}
<h1>Consent {{service.name}}</h1>
<h3>Request Information:</h3>
<ul>
<li>Service name: {{service.service_name}}</li>
<li>Requested at: {{service.request_time}}</li>
<li>Auth methode: {{service.expires_at}}</li>
<li>Service State: {{service.state}}</li>
</ul>
{% if message %}
{% include "_message" (message=message.message, type=message.level) %}
{% endif %}
{% if service.state in _inputStates %}
{% include "_consent_form" %}
{% else %}
{% include "_consent_noinput" %}
{% endif %}
{% endblock %}