diff --git a/Cargo.lock b/Cargo.lock index c995eff1..ffcff3dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1296,6 +1296,7 @@ dependencies = [ "actix-http", "actix-identity", "actix-rt", + "actix-service", "actix-web", "argon2-creds", "cache-buster", diff --git a/Cargo.toml b/Cargo.toml index 8b7130ad..8fe3b615 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ actix-identity = "0.3" actix-http = "2.2" actix-rt = "1" actix-cors= "0.5.4" +actix-service = "1.0.6" mime_guess = "2.0.3" diff --git a/build.rs b/build.rs index 77d28a8f..531a6502 100644 --- a/build.rs +++ b/build.rs @@ -47,8 +47,8 @@ fn cache_bust() { ]; let config = BusterBuilder::default() - .source("./static") - .result("./prod") + .source("./static-assets") + .result("./static") .mime_types(types) .copy(true) .follow_links(true) diff --git a/src/api/v1/auth.rs b/src/api/v1/auth.rs index 209fbac0..b2293856 100644 --- a/src/api/v1/auth.rs +++ b/src/api/v1/auth.rs @@ -252,7 +252,7 @@ pub async fn signout(id: Identity) -> impl Responder { if let Some(_) = id.identity() { id.forget(); } - HttpResponse::TemporaryRedirect() + HttpResponse::Found() .set_header(header::LOCATION, "/login") .body("") } diff --git a/src/api/v1/tests/auth.rs b/src/api/v1/tests/auth.rs index 3efd9eda..96339a3e 100644 --- a/src/api/v1/tests/auth.rs +++ b/src/api/v1/tests/auth.rs @@ -130,7 +130,7 @@ async fn auth_works() { .to_request(), ) .await; - assert_eq!(signout_resp.status(), StatusCode::TEMPORARY_REDIRECT); + assert_eq!(signout_resp.status(), StatusCode::FOUND); } #[actix_rt::test] diff --git a/src/cache_buster_data.json b/src/cache_buster_data.json index f59f62bc..3710f6db 100644 --- a/src/cache_buster_data.json +++ b/src/cache_buster_data.json @@ -1 +1 @@ -{"map":{"./static/img/svg/github.svg":"./prod/img/svg/github.FA9EB1C66F548EC2C7598B94BA6A17275E1EA383D42B6C83351A2388C773E621.svg","./static/img/svg/globe.svg":"./prod/img/svg/globe.44C2A069EBD637663E938ECE7B8E4EC2A8BDE049A8A044EC68D9CB69AE8C592E.svg","./static/img/svg/message-square.svg":"./prod/img/svg/message-square.E246A6B2AAEFCE8A62B9BDD2D155D3B4923C3E48325EAEF099D509A2D7BB4DD1.svg","./static/img/svg/shield.svg":"./prod/img/svg/shield.13AFE15DCB4882B4A940CFDC3E2088A733CD4E6F97F25B211D87C7C9D6DBA2B6.svg","./static/img/svg/filter.svg":"./prod/img/svg/filter.6D5FBD96BA2E2020663AAC4994A991295917D73F3592C07EE103647B655A2275.svg","./static/img/svg/moon.svg":"./prod/img/svg/moon.1E151D68949CA3B2DC7DE34BC25B7586E4175AC3BA7F56DDBB34227334EF7155.svg","./static/img/svg/toggle-left.svg":"./prod/img/svg/toggle-left.E421950C5922E84015F0A86F272AE5637A2ED96E267D2C962543F5994E5D1172.svg","./static/img/svg/menu.svg":"./prod/img/svg/menu.A2C4DD00686F5D23F78885AC4CE3E075FCA78DFBDEA70407667FBBD9801B7A75.svg","./static/img/icon.png":"./prod/img/icon.CC75A040D5F432E5DC9043D10B94BF1FC3BAE1D02A8C2030F655E642EAD4A32C.png","./static/img/svg/key.svg":"./prod/img/svg/key.F0AACBED8D0F7A279977392F92F4DA73C35E905AC73B3C83320D54856E627EEC.svg","./static/img/svg/help-circle.svg":"./prod/img/svg/help-circle.BE230ABD2E05EB05EF6C5B7D04D35A3A43637EF1E046DEF3D244425609B99F81.svg","./static/img/svg/file.svg":"./prod/img/svg/file.F9E376D9F78FFD918D8D592A8B2D97EAAC14E638B5A7AE3C58DDB075375D8E0E.svg","./static/img/icon-trans.png":"./prod/img/icon-trans.7920418313D84DCDB2491E02E52E4BEF374970C216E85BD721274EE51241ECD4.png","./static/img/svg/shield-off.svg":"./prod/img/svg/shield-off.85394A6AD92D550F8EBA72AAB095E078E7A0E3359DF81174532C8D1AF53B5876.svg","./static/img/svg/eye-off.svg":"./prod/img/svg/eye-off.939360B335D1D35B57C3E2070129D14ABB168E4AC137B5BE4F6F8BD450B712F5.svg","./static/img/svg/credit-card.svg":"./prod/img/svg/credit-card.DF612AFE367A7B31410F2F6CD3C7B515B0F1889C0107EA695D840DFFA492E07D.svg","./static/img/svg/settings.svg":"./prod/img/svg/settings.910C6241743C9C694141971BE8E1C4016A1A5BF203E4E9D676D4CE93BD518F4C.svg","./static/img/svg/user.svg":"./prod/img/svg/user.B164ECD2C4A09DC5189F1F252487E2AC6A33646BEA67AF9C528CDA61FE5E146F.svg","./static/img/svg/toggle-right.svg":"./prod/img/svg/toggle-right.15BF49887941593CE3FE09FA73E3CAF1F4B1E8ABCB42A23D85B4FCBC24FDF5AA.svg","./static/img/svg/eye.svg":"./prod/img/svg/eye.9DE4D24D3C9B055D02B94A8AD65E8C0C644852381FDD131A64448B6DA7859167.svg","./static/img/svg/tag.svg":"./prod/img/svg/tag.E0BC111B8E81BBFC62B6A9E7E4AC162B7085A6543D995B7A0030CB7632901BD4.svg","./static/bundle/main.css":"./prod/bundle/main.C7B0ACE647935B5E61BD692A0EB6AFF167CAB2F80483079378CF7A18D7FF9466.css","./static/img/svg/file-text.svg":"./prod/img/svg/file-text.CF57DF252051E7E81C240D36AF1DB8A9DDAF282F9A5E8C338408FE88A6545A02.svg","./static/bundle/main.js":"./prod/bundle/main.736EA02160A042CFB6310C65CB61D8F2578A457254FBDBD1F00009320D8BF903.js","./static/img/svg/bell.svg":"./prod/img/svg/bell.9DA292704EE9907EFDB870F4510C97336977CA27FBFAAD83CF46F8E22D3828F7.svg","./static/img/svg/home.svg":"./prod/img/svg/home.28C26C2D3E4013D24D755A589A80D8DD5C49DA5397032E3F09B76BC3A2C314ED.svg","./static/img/svg/log-out.svg":"./prod/img/svg/log-out.92AB4384FD41D9AFE4735C480361BB64789CD767B7DD0FF3C6F56287B3D4498E.svg"},"base_dir":"./prod"} \ No newline at end of file +{"map":{"./static-assets/img/svg/filter.svg":"./static/img/svg/filter.6D5FBD96BA2E2020663AAC4994A991295917D73F3592C07EE103647B655A2275.svg","./static-assets/img/svg/home.svg":"./static/img/svg/home.28C26C2D3E4013D24D755A589A80D8DD5C49DA5397032E3F09B76BC3A2C314ED.svg","./static-assets/img/svg/shield.svg":"./static/img/svg/shield.13AFE15DCB4882B4A940CFDC3E2088A733CD4E6F97F25B211D87C7C9D6DBA2B6.svg","./static-assets/img/svg/eye.svg":"./static/img/svg/eye.9DE4D24D3C9B055D02B94A8AD65E8C0C644852381FDD131A64448B6DA7859167.svg","./static-assets/img/svg/settings.svg":"./static/img/svg/settings.910C6241743C9C694141971BE8E1C4016A1A5BF203E4E9D676D4CE93BD518F4C.svg","./static-assets/img/svg/message-square.svg":"./static/img/svg/message-square.E246A6B2AAEFCE8A62B9BDD2D155D3B4923C3E48325EAEF099D509A2D7BB4DD1.svg","./static-assets/img/svg/eye-off.svg":"./static/img/svg/eye-off.939360B335D1D35B57C3E2070129D14ABB168E4AC137B5BE4F6F8BD450B712F5.svg","./static-assets/img/svg/toggle-left.svg":"./static/img/svg/toggle-left.E421950C5922E84015F0A86F272AE5637A2ED96E267D2C962543F5994E5D1172.svg","./static-assets/img/svg/user.svg":"./static/img/svg/user.B164ECD2C4A09DC5189F1F252487E2AC6A33646BEA67AF9C528CDA61FE5E146F.svg","./static-assets/img/svg/globe.svg":"./static/img/svg/globe.44C2A069EBD637663E938ECE7B8E4EC2A8BDE049A8A044EC68D9CB69AE8C592E.svg","./static-assets/img/svg/shield-off.svg":"./static/img/svg/shield-off.85394A6AD92D550F8EBA72AAB095E078E7A0E3359DF81174532C8D1AF53B5876.svg","./static-assets/img/svg/tag.svg":"./static/img/svg/tag.E0BC111B8E81BBFC62B6A9E7E4AC162B7085A6543D995B7A0030CB7632901BD4.svg","./static-assets/img/svg/moon.svg":"./static/img/svg/moon.1E151D68949CA3B2DC7DE34BC25B7586E4175AC3BA7F56DDBB34227334EF7155.svg","./static-assets/img/svg/key.svg":"./static/img/svg/key.F0AACBED8D0F7A279977392F92F4DA73C35E905AC73B3C83320D54856E627EEC.svg","./static-assets/img/svg/credit-card.svg":"./static/img/svg/credit-card.DF612AFE367A7B31410F2F6CD3C7B515B0F1889C0107EA695D840DFFA492E07D.svg","./static-assets/img/svg/log-out.svg":"./static/img/svg/log-out.92AB4384FD41D9AFE4735C480361BB64789CD767B7DD0FF3C6F56287B3D4498E.svg","./static-assets/img/svg/bell.svg":"./static/img/svg/bell.9DA292704EE9907EFDB870F4510C97336977CA27FBFAAD83CF46F8E22D3828F7.svg","./static-assets/img/svg/github.svg":"./static/img/svg/github.FA9EB1C66F548EC2C7598B94BA6A17275E1EA383D42B6C83351A2388C773E621.svg","./static-assets/img/svg/menu.svg":"./static/img/svg/menu.A2C4DD00686F5D23F78885AC4CE3E075FCA78DFBDEA70407667FBBD9801B7A75.svg","./static-assets/img/icon.png":"./static/img/icon.CC75A040D5F432E5DC9043D10B94BF1FC3BAE1D02A8C2030F655E642EAD4A32C.png","./static-assets/img/svg/file.svg":"./static/img/svg/file.F9E376D9F78FFD918D8D592A8B2D97EAAC14E638B5A7AE3C58DDB075375D8E0E.svg","./static-assets/bundle/main.js":"./static/bundle/main.47250AD075BB60388779EF82D1C6A084AB82B69A9061D8A4DFCF1C18C07A0C4F.js","./static-assets/bundle/main.css":"./static/bundle/main.C7B0ACE647935B5E61BD692A0EB6AFF167CAB2F80483079378CF7A18D7FF9466.css","./static-assets/img/svg/file-text.svg":"./static/img/svg/file-text.CF57DF252051E7E81C240D36AF1DB8A9DDAF282F9A5E8C338408FE88A6545A02.svg","./static-assets/img/svg/help-circle.svg":"./static/img/svg/help-circle.BE230ABD2E05EB05EF6C5B7D04D35A3A43637EF1E046DEF3D244425609B99F81.svg","./static-assets/img/icon-trans.png":"./static/img/icon-trans.7920418313D84DCDB2491E02E52E4BEF374970C216E85BD721274EE51241ECD4.png","./static-assets/img/svg/toggle-right.svg":"./static/img/svg/toggle-right.15BF49887941593CE3FE09FA73E3CAF1F4B1E8ABCB42A23D85B4FCBC24FDF5AA.svg"},"base_dir":"./static"} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 3addae19..3c9ecc84 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,10 +18,9 @@ use std::env; use actix_identity::{CookieIdentityPolicy, IdentityService}; use actix_web::{ - client::Client, error::InternalError, http::StatusCode, middleware, web::JsonConfig, App, - HttpServer, + client::Client, error::InternalError, http::StatusCode, middleware as actix_middleware, + web::JsonConfig, App, HttpServer, }; -use cache_buster::Files as FileMap; use lazy_static::lazy_static; use log::info; @@ -35,19 +34,18 @@ mod templates; #[cfg(test)] #[macro_use] mod tests; +mod middleware; pub use data::Data; pub use settings::Settings; +use static_assets::FileMap; lazy_static! { pub static ref SETTINGS: Settings = Settings::new().unwrap(); pub static ref S: String = env::var("S").unwrap(); - pub static ref FILES: FileMap = { - let map = include_str!("cache_buster_data.json"); - FileMap::new(&map) - }; - pub static ref JS: &'static str = FILES.get("./static/bundle/main.js").unwrap(); - pub static ref CSS: &'static str = FILES.get("./static/bundle/main.css").unwrap(); + pub static ref FILES: FileMap = FileMap::new(); + pub static ref JS: &'static str = FILES.get("./static-assets/bundle/main.js").unwrap(); + pub static ref CSS: &'static str = FILES.get("./static-assets/bundle/main.css").unwrap(); } pub static OPEN_API_DOC: &str = env!("OPEN_API_DOCS"); @@ -77,19 +75,19 @@ async fn main() -> std::io::Result<()> { let client = Client::default(); App::new() - .wrap(middleware::Logger::default()) + .wrap(actix_middleware::Logger::default()) .wrap(get_identity_service()) - .wrap(middleware::Compress::default()) + .wrap(actix_middleware::Compress::default()) .data(data.clone()) .data(client.clone()) - .wrap(middleware::NormalizePath::new( - middleware::normalize::TrailingSlash::Trim, + .wrap(actix_middleware::NormalizePath::new( + actix_middleware::normalize::TrailingSlash::Trim, )) .configure(v1::pow::services) .configure(v1::services) .configure(docs::services) - .configure(templates::services) .configure(static_assets::services) + .configure(templates::services) .app_data(get_json_err()) }) .bind(SETTINGS.server.get_ip()) diff --git a/src/middleware/auth.rs b/src/middleware/auth.rs new file mode 100644 index 00000000..20416cf2 --- /dev/null +++ b/src/middleware/auth.rs @@ -0,0 +1,126 @@ +/* +* Copyright (C) 2021 Aravinth Manivannan +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see . +*/ + +#![allow(clippy::type_complexity)] +use std::task::{Context, Poll}; + +use actix_identity::Identity; +//use actix_identity::{CookieIdentityPolicy, IdentityService}; +use actix_service::{Service, Transform}; +use actix_web::dev::{ServiceRequest, ServiceResponse}; +use actix_web::{http, Error, FromRequest, HttpResponse}; + +use futures::future::{ok, Either, Ready}; + +pub struct CheckLogin; + +const LOGIN_ROUTE: &str = "/login"; + +impl Transform for CheckLogin +where + S: Service, Error = Error>, + S::Future: 'static, +{ + type Request = ServiceRequest; + type Response = ServiceResponse; + type Error = Error; + type Transform = CheckLoginMiddleware; + type InitError = (); + type Future = Ready>; + + fn new_transform(&self, service: S) -> Self::Future { + ok(CheckLoginMiddleware { service }) + } +} +// +//pub fn auto_login(req: &HttpRequest, pl: &mut dev::Payload) -> Option<()> { +// dbg!("login"); +// if let Some(_) = Identity::from_request(req, pl) +// .into_inner() +// .map(|x| x.identity()) +// .unwrap() +// { +// Some(()) +// } else { +// None +// } +//} +// +//fn not_auth(path: &str) -> bool { +// let paths = ["/login", "/css", "/img", "/js"]; +// paths.iter().any(|x| path.starts_with(x)) +//} + +pub struct CheckLoginMiddleware { + service: S, +} + +impl Service for CheckLoginMiddleware +where + S: Service, Error = Error>, + S::Future: 'static, +{ + type Request = ServiceRequest; + type Response = ServiceResponse; + type Error = Error; + type Future = Either>>; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.service.poll_ready(cx) + } + + fn call(&mut self, req: ServiceRequest) -> Self::Future { + // if not_auth(req.path()) { + // return Either::Left(self.service.call(req)); + // }; + let (r, mut pl) = req.into_parts(); + + // TODO investigate when the bellow statement will + // return error + if let Ok(Some(_)) = Identity::from_request(&r, &mut pl) + .into_inner() + .map(|x| x.identity()) + { + let req = ServiceRequest::from_parts(r, pl).ok().unwrap(); + Either::Left(self.service.call(req)) + // Some(()) + } else { + let req = ServiceRequest::from_parts(r, pl).ok().unwrap(); + Either::Right(ok(req.into_response( + HttpResponse::Found() + .header(http::header::LOCATION, LOGIN_ROUTE) + .finish() + .into_body(), + ))) + + //None + } + + // let token = auto_login(&r, &mut pl); + // let req = ServiceRequest::from_parts(r, pl).ok().unwrap(); + // if token.is_some() { + // Either::Left(self.service.call(req)) + // } else { + // Either::Right(ok(req.into_response( + // HttpResponse::Found() + // .header(http::header::LOCATION, LOGIN_ROUTE) + // .finish() + // .into_body(), + // ))) + // } + } +} diff --git a/src/middleware/mod.rs b/src/middleware/mod.rs new file mode 100644 index 00000000..62539e84 --- /dev/null +++ b/src/middleware/mod.rs @@ -0,0 +1,18 @@ +/* +* Copyright (C) 2021 Aravinth Manivannan +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see . +*/ + +pub mod auth; diff --git a/src/static_assets.rs b/src/static_assets.rs index 193c25ba..9eff5782 100644 --- a/src/static_assets.rs +++ b/src/static_assets.rs @@ -17,13 +17,14 @@ use actix_web::body::Body; use actix_web::{get, web, HttpResponse, Responder}; +use cache_buster::Files; use mime_guess::from_path; use rust_embed::RustEmbed; use std::borrow::Cow; #[derive(RustEmbed)] -#[folder = "prod/"] +#[folder = "static/"] struct Asset; pub fn handle_embedded_file(path: &str) -> HttpResponse { @@ -41,7 +42,7 @@ pub fn handle_embedded_file(path: &str) -> HttpResponse { } } -#[get("/{_:.*}")] +#[get("/static/{_:.*}")] async fn dist(path: web::Path) -> impl Responder { handle_embedded_file(&path.0) } @@ -50,6 +51,29 @@ pub fn services(cfg: &mut web::ServiceConfig) { cfg.service(dist); } +pub struct FileMap { + files: Files, +} + +impl FileMap { + pub fn new() -> Self { + let map = include_str!("cache_buster_data.json"); + let files = Files::new(&map); + Self { files } + } + pub fn get<'a>(&'a self, path: &'a str) -> Option<&'a str> { + // let file_path = self.files.get(path); + let file_path = self.files.get_full_path(path); + + if file_path.is_some() { + let file_path = &file_path.unwrap()[1..]; + return Some(file_path); + } else { + return None; + } + } +} + #[cfg(test)] mod tests { use actix_web::http::StatusCode; @@ -69,4 +93,12 @@ mod tests { .await; assert_eq!(resp.status(), StatusCode::OK); } + + #[test] + fn filemap_works() { + let files = super::FileMap::new(); + let css = files.get("./static-assets/bundle/main.css").unwrap(); + println!("{}", css); + assert!(css.contains("/static/bundle/main")); + } } diff --git a/src/templates/mod.rs b/src/templates/mod.rs index 9ea40217..cd7d1c4a 100644 --- a/src/templates/mod.rs +++ b/src/templates/mod.rs @@ -20,13 +20,13 @@ use actix_web::web::ServiceConfig; mod auth; mod panel; -pub fn services(cfg: &mut ServiceConfig) { - cfg.service(auth::login::login); - cfg.service(auth::register::join); +pub use crate::middleware::auth::CheckLogin; - // panel +pub fn services(cfg: &mut ServiceConfig) { cfg.service(panel::panel); cfg.service(panel::sitekey::add_sitekey); + cfg.service(auth::login::login); + cfg.service(auth::register::join); } #[cfg(not(tarpaulin_include))] @@ -39,18 +39,27 @@ mod tests { use crate::*; #[actix_rt::test] - async fn templates_work() { + async fn protected_pages_templates_work() { let mut app = test::init_service(App::new().configure(services)).await; - let urls = vec!["/", "/join", "/login", "/sitekey/add"]; + let urls = vec!["/", "/sitekey/add"]; for url in urls.iter() { let resp = test::call_service(&mut app, test::TestRequest::get().uri(url).to_request()).await; - if url == urls.get(0).unwrap() { - assert_eq!(resp.status(), StatusCode::TEMPORARY_REDIRECT); - } else { - assert_eq!(resp.status(), StatusCode::OK); - } + assert_eq!(resp.status(), StatusCode::FOUND); + } + } + + #[actix_rt::test] + async fn public_pages_tempaltes_work() { + let mut app = test::init_service(App::new().configure(services)).await; + let urls = vec!["/join", "/login"]; + + for url in urls.iter() { + let resp = + test::call_service(&mut app, test::TestRequest::get().uri(url).to_request()).await; + + assert_eq!(resp.status(), StatusCode::OK); } } } diff --git a/src/templates/panel/mod.rs b/src/templates/panel/mod.rs index ee7ca03c..4bda7c42 100644 --- a/src/templates/panel/mod.rs +++ b/src/templates/panel/mod.rs @@ -21,6 +21,7 @@ use actix_web::{get, HttpResponse, Responder}; use sailfish::TemplateOnce; use crate::api::v1::auth::is_authenticated; +pub use crate::middleware::auth::CheckLogin; pub mod sitekey; @@ -42,7 +43,7 @@ impl<'a> Default for IndexPage<'a> { } } -#[get("/")] +#[get("/", wrap = "CheckLogin")] pub async fn panel(id: Identity) -> impl Responder { if is_authenticated(&id).is_err() { return HttpResponse::TemporaryRedirect() diff --git a/src/templates/panel/sitekey.rs b/src/templates/panel/sitekey.rs index 5cd180b2..fe198454 100644 --- a/src/templates/panel/sitekey.rs +++ b/src/templates/panel/sitekey.rs @@ -18,6 +18,8 @@ use actix_web::{get, HttpResponse, Responder}; use sailfish::TemplateOnce; +use super::CheckLogin; + #[derive(TemplateOnce, Clone)] #[template(path = "panel/add-site-key/index.html")] pub struct IndexPage<'a> { @@ -36,7 +38,7 @@ impl<'a> Default for IndexPage<'a> { } } -#[get("/sitekey/add")] +#[get("/sitekey/add", wrap = "CheckLogin")] pub async fn add_sitekey() -> impl Responder { let body = IndexPage::default().render_once().unwrap(); HttpResponse::Ok() diff --git a/static/bundle/main.css b/static-assets/bundle/main.css similarity index 100% rename from static/bundle/main.css rename to static-assets/bundle/main.css diff --git a/static/bundle/main.js b/static-assets/bundle/main.js similarity index 79% rename from static/bundle/main.js rename to static-assets/bundle/main.js index 8053e24f..50ddd2c2 100644 --- a/static/bundle/main.js +++ b/static-assets/bundle/main.js @@ -1 +1 @@ -!function(e){var t={};function n(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return e[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(a,r,function(t){return e[t]}.bind(null,r));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}([function(e,t,n){},function(e,t,n){},function(e,t,n){"use strict";n.r(t);const a=e=>{if(!e)throw new Error("uri is empty");if("string"!=typeof e)throw new TypeError("URI must be a string");let t=e.length;return"/"==e[t-1]&&(e=e.slice(0,t-1)),e};var r={registerUser:"/api/v1/signup",loginUser:"/api/v1/signin",signoutUser:"/api/v1/signout",deleteAccount:"/api/v1/account/delete",usernameExists:"/api/v1/account/username/exists",emailExists:"/api/v1/account/email/exists",healthCheck:"/api/v1/meta/health",buildDetails:"/api/v1/meta/build",addDomain:"/api/v1/mcaptcha/domain/add",challengeDomain:"/api/v1/mcaptcha/domain/domain/verify/challenge/get",proveDomain:"/api/v1/mcaptcha/domain/domain/verify/challenge/prove",deleteDomain:"/api/v1/mcaptcha/domain/delete",addToken:"/api/v1/mcaptcha/domain/token/add",updateTokenKey:"/api/v1/mcaptcha/domain/token/update",getTokenKey:"/api/v1/mcaptcha/domain/token/get",deleteToken:"/api/v1/mcaptcha/domain/token/delete",addTokenLevels:"/api/v1/mcaptcha/domain/token/levels/add",updateTokenLevels:"/api/v1/mcaptcha/domain/token/levels/update",deleteTokenLevels:"/api/v1/mcaptcha/domain/token/levels/delete",getTokenLevels:"/api/v1/mcaptcha/domain/token/levels/get",getTokenDuration:"/api/v1/mcaptcha/domain/token/token/get",updateTokenDuration:"/api/v1/mcaptcha/domain/token/token/update"};var o={registerUser:"/join/",loginUser:"/login/",signoutUser:"/api/v1/signout",panelHome:"/",docsHome:"/docs/"};var i=e=>({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});const s=e=>{e.preventDefault();let t=document.getElementById("username").value;i(e,t,"username");let n=document.getElementById("password").value;fetch(r.loginUser,i({username:t,password:n})).then(e=>{e.ok?(alert("success"),window.location.assign(o.panelHome)):e.json().then(e=>alert("error: "+e.error))})};var l=async function(){let e=document.getElementById("username"),t={val:e.value},n=await fetch(r.usernameExists,i(t));if(n.ok){let t=await n.json();return t.exists&&(e.className+=" form__in-field--warn",alert("Username taken")),t.exists}{let e=await n.json();alert("error: "+e.error)}return!1};const u=async e=>{e.preventDefault();let t=document.getElementById("username").value;i(e,t,"username");let n=document.getElementById("password").value;if(n!=document.getElementById("password-check").value)return alert("passwords don't match, check again!");let a=await l();if(a)return;let s=document.getElementById("email").value;if(s.replace(/\s/g,"").length){if(a=await(async()=>{let e=document.getElementById("email"),t={val:e.value},n=await fetch(r.emailExists,i(t));if(n.ok){let t=await n.json();return t.exists&&(e.className+=" form__in-field--warn",alert("Email taken")),t.exists}{let e=await n.json();alert("error: "+e.error)}})(),a)return}else s=null;let u={username:t,password:n,email:s},c=await fetch(r.registerUser,i(u));if(c.ok)alert("success"),window.location.assign(o.loginUser);else{let e=await c.json();alert("error: "+e.error)}},c=()=>{};n(0),n(1);const d=new class{constructor(){this.routes=[]}register(e,t){if(!e)throw new Error("uri is empty");if(!t)throw new Error("fn is empty");if("string"!=typeof e)throw new TypeError("URI must be a string");if("function"!=typeof t)throw new TypeError("a callback fn must be provided");this.routes.forEach(t=>{if(t.uri==e)throw new Error(`URI exists. provided URI: ${e}, registered config: ${t}`)});const n={uri:e=a(e),fn:t};this.routes.push(n)}route(){this.routes.forEach(e=>{let t=new RegExp(`^${e.uri}$`),n=window.location.pathname;if(n=a(n),n.match(t))return e.fn.call()})}};d.register("/",c),d.register("/register",()=>{document.getElementById("form").addEventListener("submit",u,!0),document.getElementById("username").addEventListener("input",l,!1)}),d.register("/login",()=>{document.getElementById("form").addEventListener("submit",s,!0)}),d.register("/panel/layout.html/",c),d.route()}]); \ No newline at end of file +!function(e){var t={};function n(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return e[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(a,r,function(t){return e[t]}.bind(null,r));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}([function(e,t,n){},function(e,t,n){},function(e,t,n){"use strict";n.r(t);const a=e=>{if(!e)throw new Error("uri is empty");if("string"!=typeof e)throw new TypeError("URI must be a string");let t=e.length;return"/"==e[t-1]&&(e=e.slice(0,t-1)),e};var r={registerUser:"/api/v1/signup",loginUser:"/api/v1/signin",signoutUser:"/api/v1/signout",deleteAccount:"/api/v1/account/delete",usernameExists:"/api/v1/account/username/exists",emailExists:"/api/v1/account/email/exists",healthCheck:"/api/v1/meta/health",buildDetails:"/api/v1/meta/build",addDomain:"/api/v1/mcaptcha/domain/add",challengeDomain:"/api/v1/mcaptcha/domain/domain/verify/challenge/get",proveDomain:"/api/v1/mcaptcha/domain/domain/verify/challenge/prove",deleteDomain:"/api/v1/mcaptcha/domain/delete",addToken:"/api/v1/mcaptcha/domain/token/add",updateTokenKey:"/api/v1/mcaptcha/domain/token/update",getTokenKey:"/api/v1/mcaptcha/domain/token/get",deleteToken:"/api/v1/mcaptcha/domain/token/delete",addTokenLevels:"/api/v1/mcaptcha/domain/token/levels/add",updateTokenLevels:"/api/v1/mcaptcha/domain/token/levels/update",deleteTokenLevels:"/api/v1/mcaptcha/domain/token/levels/delete",getTokenLevels:"/api/v1/mcaptcha/domain/token/levels/get",getTokenDuration:"/api/v1/mcaptcha/domain/token/token/get",updateTokenDuration:"/api/v1/mcaptcha/domain/token/token/update"};var o={registerUser:"/join/",loginUser:"/login/",signoutUser:"/api/v1/signout",panelHome:"/",docsHome:"/docs/"};var i=e=>({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});const s=e=>{e.preventDefault();let t=document.getElementById("username").value;i(e,t,"username");let n=document.getElementById("password").value;fetch(r.loginUser,i({username:t,password:n})).then(e=>{e.ok?(alert("success"),window.location.assign(o.panelHome)):e.json().then(e=>alert("error: "+e.error))})};var l=async function(){let e=document.getElementById("username"),t={val:e.value},n=await fetch(r.usernameExists,i(t));if(n.ok){let t=await n.json();return t.exists&&(e.className+=" form__in-field--warn",alert("Username taken")),t.exists}{let e=await n.json();alert("error: "+e.error)}return!1};const u=async e=>{e.preventDefault();let t=document.getElementById("username").value;i(e,t,"username");let n=document.getElementById("password").value;if(n!=document.getElementById("password-check").value)return alert("passwords don't match, check again!");let a=await l();if(a)return;let s=document.getElementById("email").value;if(s.replace(/\s/g,"").length){if(a=await(async()=>{let e=document.getElementById("email"),t={val:e.value},n=await fetch(r.emailExists,i(t));if(n.ok){let t=await n.json();return t.exists&&(e.className+=" form__in-field--warn",alert("Email taken")),t.exists}{let e=await n.json();alert("error: "+e.error)}})(),a)return}else s=null;let u={username:t,password:n,email:s},c=await fetch(r.registerUser,i(u));if(c.ok)alert("success"),window.location.assign(o.loginUser);else{let e=await c.json();alert("error: "+e.error)}};n(0),n(1);const c=new class{constructor(){this.routes=[]}register(e,t){if(!e)throw new Error("uri is empty");if(!t)throw new Error("fn is empty");if("string"!=typeof e)throw new TypeError("URI must be a string");if("function"!=typeof t)throw new TypeError("a callback fn must be provided");this.routes.forEach(t=>{if(t.uri==e)throw new Error(`URI exists. provided URI: ${e}, registered config: ${t}`)});const n={uri:e=a(e),fn:t};this.routes.push(n)}route(){this.routes.forEach(e=>{let t=new RegExp(`^${e.uri}$`),n=window.location.pathname;if(n=a(n),n.match(t))return e.fn.call()})}};c.register(o.panelHome,()=>{}),c.register(o.registerUser,()=>{document.getElementById("form").addEventListener("submit",u,!0),document.getElementById("username").addEventListener("input",l,!1)}),c.register(o.loginUser,()=>{document.getElementById("form").addEventListener("submit",s,!0)}),c.route()}]); \ No newline at end of file diff --git a/static/img/icon-trans.png b/static-assets/img/icon-trans.png similarity index 100% rename from static/img/icon-trans.png rename to static-assets/img/icon-trans.png diff --git a/static/img/icon.png b/static-assets/img/icon.png similarity index 100% rename from static/img/icon.png rename to static-assets/img/icon.png diff --git a/static/img/svg/bell.svg b/static-assets/img/svg/bell.svg similarity index 100% rename from static/img/svg/bell.svg rename to static-assets/img/svg/bell.svg diff --git a/static/img/svg/credit-card.svg b/static-assets/img/svg/credit-card.svg similarity index 100% rename from static/img/svg/credit-card.svg rename to static-assets/img/svg/credit-card.svg diff --git a/static/img/svg/eye-off.svg b/static-assets/img/svg/eye-off.svg similarity index 100% rename from static/img/svg/eye-off.svg rename to static-assets/img/svg/eye-off.svg diff --git a/static/img/svg/eye.svg b/static-assets/img/svg/eye.svg similarity index 100% rename from static/img/svg/eye.svg rename to static-assets/img/svg/eye.svg diff --git a/static/img/svg/file-text.svg b/static-assets/img/svg/file-text.svg similarity index 100% rename from static/img/svg/file-text.svg rename to static-assets/img/svg/file-text.svg diff --git a/static/img/svg/file.svg b/static-assets/img/svg/file.svg similarity index 100% rename from static/img/svg/file.svg rename to static-assets/img/svg/file.svg diff --git a/static/img/svg/filter.svg b/static-assets/img/svg/filter.svg similarity index 100% rename from static/img/svg/filter.svg rename to static-assets/img/svg/filter.svg diff --git a/static/img/svg/github.svg b/static-assets/img/svg/github.svg similarity index 100% rename from static/img/svg/github.svg rename to static-assets/img/svg/github.svg diff --git a/static/img/svg/globe.svg b/static-assets/img/svg/globe.svg similarity index 100% rename from static/img/svg/globe.svg rename to static-assets/img/svg/globe.svg diff --git a/static/img/svg/help-circle.svg b/static-assets/img/svg/help-circle.svg similarity index 100% rename from static/img/svg/help-circle.svg rename to static-assets/img/svg/help-circle.svg diff --git a/static/img/svg/home.svg b/static-assets/img/svg/home.svg similarity index 100% rename from static/img/svg/home.svg rename to static-assets/img/svg/home.svg diff --git a/static/img/svg/key.svg b/static-assets/img/svg/key.svg similarity index 100% rename from static/img/svg/key.svg rename to static-assets/img/svg/key.svg diff --git a/static/img/svg/log-out.svg b/static-assets/img/svg/log-out.svg similarity index 100% rename from static/img/svg/log-out.svg rename to static-assets/img/svg/log-out.svg diff --git a/static/img/svg/menu.svg b/static-assets/img/svg/menu.svg similarity index 100% rename from static/img/svg/menu.svg rename to static-assets/img/svg/menu.svg diff --git a/static/img/svg/message-square.svg b/static-assets/img/svg/message-square.svg similarity index 100% rename from static/img/svg/message-square.svg rename to static-assets/img/svg/message-square.svg diff --git a/static/img/svg/moon.svg b/static-assets/img/svg/moon.svg similarity index 100% rename from static/img/svg/moon.svg rename to static-assets/img/svg/moon.svg diff --git a/static/img/svg/settings.svg b/static-assets/img/svg/settings.svg similarity index 100% rename from static/img/svg/settings.svg rename to static-assets/img/svg/settings.svg diff --git a/static/img/svg/shield-off.svg b/static-assets/img/svg/shield-off.svg similarity index 100% rename from static/img/svg/shield-off.svg rename to static-assets/img/svg/shield-off.svg diff --git a/static/img/svg/shield.svg b/static-assets/img/svg/shield.svg similarity index 100% rename from static/img/svg/shield.svg rename to static-assets/img/svg/shield.svg diff --git a/static/img/svg/tag.svg b/static-assets/img/svg/tag.svg similarity index 100% rename from static/img/svg/tag.svg rename to static-assets/img/svg/tag.svg diff --git a/static/img/svg/toggle-left.svg b/static-assets/img/svg/toggle-left.svg similarity index 100% rename from static/img/svg/toggle-left.svg rename to static-assets/img/svg/toggle-left.svg diff --git a/static/img/svg/toggle-right.svg b/static-assets/img/svg/toggle-right.svg similarity index 100% rename from static/img/svg/toggle-right.svg rename to static-assets/img/svg/toggle-right.svg diff --git a/static/img/svg/user.svg b/static-assets/img/svg/user.svg similarity index 100% rename from static/img/svg/user.svg rename to static-assets/img/svg/user.svg diff --git a/static/img/icon-trans.7920418313D84DCDB2491E02E52E4BEF374970C216E85BD721274EE51241ECD4.png b/static/img/icon-trans.7920418313D84DCDB2491E02E52E4BEF374970C216E85BD721274EE51241ECD4.png new file mode 100644 index 00000000..db8da876 Binary files /dev/null and b/static/img/icon-trans.7920418313D84DCDB2491E02E52E4BEF374970C216E85BD721274EE51241ECD4.png differ diff --git a/static/img/icon.CC75A040D5F432E5DC9043D10B94BF1FC3BAE1D02A8C2030F655E642EAD4A32C.png b/static/img/icon.CC75A040D5F432E5DC9043D10B94BF1FC3BAE1D02A8C2030F655E642EAD4A32C.png new file mode 100644 index 00000000..75bf7879 Binary files /dev/null and b/static/img/icon.CC75A040D5F432E5DC9043D10B94BF1FC3BAE1D02A8C2030F655E642EAD4A32C.png differ diff --git a/static/img/svg/bell.9DA292704EE9907EFDB870F4510C97336977CA27FBFAAD83CF46F8E22D3828F7.svg b/static/img/svg/bell.9DA292704EE9907EFDB870F4510C97336977CA27FBFAAD83CF46F8E22D3828F7.svg new file mode 100644 index 00000000..c0ed0e1e --- /dev/null +++ b/static/img/svg/bell.9DA292704EE9907EFDB870F4510C97336977CA27FBFAAD83CF46F8E22D3828F7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/credit-card.DF612AFE367A7B31410F2F6CD3C7B515B0F1889C0107EA695D840DFFA492E07D.svg b/static/img/svg/credit-card.DF612AFE367A7B31410F2F6CD3C7B515B0F1889C0107EA695D840DFFA492E07D.svg new file mode 100644 index 00000000..9429a635 --- /dev/null +++ b/static/img/svg/credit-card.DF612AFE367A7B31410F2F6CD3C7B515B0F1889C0107EA695D840DFFA492E07D.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/eye-off.939360B335D1D35B57C3E2070129D14ABB168E4AC137B5BE4F6F8BD450B712F5.svg b/static/img/svg/eye-off.939360B335D1D35B57C3E2070129D14ABB168E4AC137B5BE4F6F8BD450B712F5.svg new file mode 100644 index 00000000..9d28c182 --- /dev/null +++ b/static/img/svg/eye-off.939360B335D1D35B57C3E2070129D14ABB168E4AC137B5BE4F6F8BD450B712F5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/eye.9DE4D24D3C9B055D02B94A8AD65E8C0C644852381FDD131A64448B6DA7859167.svg b/static/img/svg/eye.9DE4D24D3C9B055D02B94A8AD65E8C0C644852381FDD131A64448B6DA7859167.svg new file mode 100644 index 00000000..44f107af --- /dev/null +++ b/static/img/svg/eye.9DE4D24D3C9B055D02B94A8AD65E8C0C644852381FDD131A64448B6DA7859167.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/file-text.CF57DF252051E7E81C240D36AF1DB8A9DDAF282F9A5E8C338408FE88A6545A02.svg b/static/img/svg/file-text.CF57DF252051E7E81C240D36AF1DB8A9DDAF282F9A5E8C338408FE88A6545A02.svg new file mode 100644 index 00000000..85186e3b --- /dev/null +++ b/static/img/svg/file-text.CF57DF252051E7E81C240D36AF1DB8A9DDAF282F9A5E8C338408FE88A6545A02.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/file.F9E376D9F78FFD918D8D592A8B2D97EAAC14E638B5A7AE3C58DDB075375D8E0E.svg b/static/img/svg/file.F9E376D9F78FFD918D8D592A8B2D97EAAC14E638B5A7AE3C58DDB075375D8E0E.svg new file mode 100644 index 00000000..fa1ecc84 --- /dev/null +++ b/static/img/svg/file.F9E376D9F78FFD918D8D592A8B2D97EAAC14E638B5A7AE3C58DDB075375D8E0E.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/filter.6D5FBD96BA2E2020663AAC4994A991295917D73F3592C07EE103647B655A2275.svg b/static/img/svg/filter.6D5FBD96BA2E2020663AAC4994A991295917D73F3592C07EE103647B655A2275.svg new file mode 100644 index 00000000..3ae2cfc7 --- /dev/null +++ b/static/img/svg/filter.6D5FBD96BA2E2020663AAC4994A991295917D73F3592C07EE103647B655A2275.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/github.FA9EB1C66F548EC2C7598B94BA6A17275E1EA383D42B6C83351A2388C773E621.svg b/static/img/svg/github.FA9EB1C66F548EC2C7598B94BA6A17275E1EA383D42B6C83351A2388C773E621.svg new file mode 100644 index 00000000..8a1c9c0a --- /dev/null +++ b/static/img/svg/github.FA9EB1C66F548EC2C7598B94BA6A17275E1EA383D42B6C83351A2388C773E621.svg @@ -0,0 +1 @@ + diff --git a/static/img/svg/globe.44C2A069EBD637663E938ECE7B8E4EC2A8BDE049A8A044EC68D9CB69AE8C592E.svg b/static/img/svg/globe.44C2A069EBD637663E938ECE7B8E4EC2A8BDE049A8A044EC68D9CB69AE8C592E.svg new file mode 100644 index 00000000..4306cdcb --- /dev/null +++ b/static/img/svg/globe.44C2A069EBD637663E938ECE7B8E4EC2A8BDE049A8A044EC68D9CB69AE8C592E.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/help-circle.BE230ABD2E05EB05EF6C5B7D04D35A3A43637EF1E046DEF3D244425609B99F81.svg b/static/img/svg/help-circle.BE230ABD2E05EB05EF6C5B7D04D35A3A43637EF1E046DEF3D244425609B99F81.svg new file mode 100644 index 00000000..1bbf3978 --- /dev/null +++ b/static/img/svg/help-circle.BE230ABD2E05EB05EF6C5B7D04D35A3A43637EF1E046DEF3D244425609B99F81.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/home.28C26C2D3E4013D24D755A589A80D8DD5C49DA5397032E3F09B76BC3A2C314ED.svg b/static/img/svg/home.28C26C2D3E4013D24D755A589A80D8DD5C49DA5397032E3F09B76BC3A2C314ED.svg new file mode 100644 index 00000000..867f0799 --- /dev/null +++ b/static/img/svg/home.28C26C2D3E4013D24D755A589A80D8DD5C49DA5397032E3F09B76BC3A2C314ED.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/key.F0AACBED8D0F7A279977392F92F4DA73C35E905AC73B3C83320D54856E627EEC.svg b/static/img/svg/key.F0AACBED8D0F7A279977392F92F4DA73C35E905AC73B3C83320D54856E627EEC.svg new file mode 100644 index 00000000..e778e74e --- /dev/null +++ b/static/img/svg/key.F0AACBED8D0F7A279977392F92F4DA73C35E905AC73B3C83320D54856E627EEC.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/log-out.92AB4384FD41D9AFE4735C480361BB64789CD767B7DD0FF3C6F56287B3D4498E.svg b/static/img/svg/log-out.92AB4384FD41D9AFE4735C480361BB64789CD767B7DD0FF3C6F56287B3D4498E.svg new file mode 100644 index 00000000..625d2724 --- /dev/null +++ b/static/img/svg/log-out.92AB4384FD41D9AFE4735C480361BB64789CD767B7DD0FF3C6F56287B3D4498E.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/menu.A2C4DD00686F5D23F78885AC4CE3E075FCA78DFBDEA70407667FBBD9801B7A75.svg b/static/img/svg/menu.A2C4DD00686F5D23F78885AC4CE3E075FCA78DFBDEA70407667FBBD9801B7A75.svg new file mode 100644 index 00000000..0ea1741e --- /dev/null +++ b/static/img/svg/menu.A2C4DD00686F5D23F78885AC4CE3E075FCA78DFBDEA70407667FBBD9801B7A75.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/message-square.E246A6B2AAEFCE8A62B9BDD2D155D3B4923C3E48325EAEF099D509A2D7BB4DD1.svg b/static/img/svg/message-square.E246A6B2AAEFCE8A62B9BDD2D155D3B4923C3E48325EAEF099D509A2D7BB4DD1.svg new file mode 100644 index 00000000..6a2e4e59 --- /dev/null +++ b/static/img/svg/message-square.E246A6B2AAEFCE8A62B9BDD2D155D3B4923C3E48325EAEF099D509A2D7BB4DD1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/moon.1E151D68949CA3B2DC7DE34BC25B7586E4175AC3BA7F56DDBB34227334EF7155.svg b/static/img/svg/moon.1E151D68949CA3B2DC7DE34BC25B7586E4175AC3BA7F56DDBB34227334EF7155.svg new file mode 100644 index 00000000..3d94f162 --- /dev/null +++ b/static/img/svg/moon.1E151D68949CA3B2DC7DE34BC25B7586E4175AC3BA7F56DDBB34227334EF7155.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/settings.910C6241743C9C694141971BE8E1C4016A1A5BF203E4E9D676D4CE93BD518F4C.svg b/static/img/svg/settings.910C6241743C9C694141971BE8E1C4016A1A5BF203E4E9D676D4CE93BD518F4C.svg new file mode 100644 index 00000000..0318f2ce --- /dev/null +++ b/static/img/svg/settings.910C6241743C9C694141971BE8E1C4016A1A5BF203E4E9D676D4CE93BD518F4C.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/shield-off.85394A6AD92D550F8EBA72AAB095E078E7A0E3359DF81174532C8D1AF53B5876.svg b/static/img/svg/shield-off.85394A6AD92D550F8EBA72AAB095E078E7A0E3359DF81174532C8D1AF53B5876.svg new file mode 100644 index 00000000..47805eed --- /dev/null +++ b/static/img/svg/shield-off.85394A6AD92D550F8EBA72AAB095E078E7A0E3359DF81174532C8D1AF53B5876.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/shield.13AFE15DCB4882B4A940CFDC3E2088A733CD4E6F97F25B211D87C7C9D6DBA2B6.svg b/static/img/svg/shield.13AFE15DCB4882B4A940CFDC3E2088A733CD4E6F97F25B211D87C7C9D6DBA2B6.svg new file mode 100644 index 00000000..18c6ed24 --- /dev/null +++ b/static/img/svg/shield.13AFE15DCB4882B4A940CFDC3E2088A733CD4E6F97F25B211D87C7C9D6DBA2B6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/tag.E0BC111B8E81BBFC62B6A9E7E4AC162B7085A6543D995B7A0030CB7632901BD4.svg b/static/img/svg/tag.E0BC111B8E81BBFC62B6A9E7E4AC162B7085A6543D995B7A0030CB7632901BD4.svg new file mode 100644 index 00000000..0c7a7704 --- /dev/null +++ b/static/img/svg/tag.E0BC111B8E81BBFC62B6A9E7E4AC162B7085A6543D995B7A0030CB7632901BD4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/toggle-left.E421950C5922E84015F0A86F272AE5637A2ED96E267D2C962543F5994E5D1172.svg b/static/img/svg/toggle-left.E421950C5922E84015F0A86F272AE5637A2ED96E267D2C962543F5994E5D1172.svg new file mode 100644 index 00000000..cd4b4e62 --- /dev/null +++ b/static/img/svg/toggle-left.E421950C5922E84015F0A86F272AE5637A2ED96E267D2C962543F5994E5D1172.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/toggle-right.15BF49887941593CE3FE09FA73E3CAF1F4B1E8ABCB42A23D85B4FCBC24FDF5AA.svg b/static/img/svg/toggle-right.15BF49887941593CE3FE09FA73E3CAF1F4B1E8ABCB42A23D85B4FCBC24FDF5AA.svg new file mode 100644 index 00000000..01392ab6 --- /dev/null +++ b/static/img/svg/toggle-right.15BF49887941593CE3FE09FA73E3CAF1F4B1E8ABCB42A23D85B4FCBC24FDF5AA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/svg/user.B164ECD2C4A09DC5189F1F252487E2AC6A33646BEA67AF9C528CDA61FE5E146F.svg b/static/img/svg/user.B164ECD2C4A09DC5189F1F252487E2AC6A33646BEA67AF9C528CDA61FE5E146F.svg new file mode 100644 index 00000000..7b5bc4a7 --- /dev/null +++ b/static/img/svg/user.B164ECD2C4A09DC5189F1F252487E2AC6A33646BEA67AF9C528CDA61FE5E146F.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/auth/login/index.html b/templates/auth/login/index.html index a6db4773..1912a147 100644 --- a/templates/auth/login/index.html +++ b/templates/auth/login/index.html @@ -1,9 +1,9 @@ <. include!("../../components/headers.html"); .>
- " class="form__logo" alt="" /> + " class="form__logo" alt="" />

Sign in to mCaptcha

-
+