panel
1
Cargo.lock
generated
@@ -1118,6 +1118,7 @@ dependencies = [
|
|||||||
name = "frontend"
|
name = "frontend"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"sailfish",
|
"sailfish",
|
||||||
|
|||||||
@@ -12,3 +12,5 @@ tokio = { version = "1.4.0", features = [ "rt-multi-thread", "macros", "fs", "te
|
|||||||
|
|
||||||
pretty_env_logger = "0.4"
|
pretty_env_logger = "0.4"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
||||||
|
lazy_static = "1.4"
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
"author": "Aravinth Manivannan <realaravinth@batsense.net>",
|
"author": "Aravinth Manivannan <realaravinth@batsense.net>",
|
||||||
"license": "AGPLv3 or above",
|
"license": "AGPLv3 or above",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cargo run && webpack-dev-server --config webpack.dev.js --open",
|
"start": "find . | entr yarn build-dev",
|
||||||
|
"build-dev": "cargo run && webpack --config webpack.dev.js",
|
||||||
|
"build-fast-dev": "cargo run && webpack-dev-server --config webpack.dev.js",
|
||||||
"build": "cargo run && webpack --config webpack.prod.js"
|
"build": "cargo run && webpack --config webpack.prod.js"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
1
frontend/sailfish.yml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
delimiter: "."
|
||||||
@@ -3,14 +3,35 @@ use sailfish::TemplateOnce;
|
|||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use tokio::io::{Error, ErrorKind};
|
use tokio::io::{Error, ErrorKind};
|
||||||
|
|
||||||
#[derive(TemplateOnce)] // automatically implement `TemplateOnce` trait
|
#[derive(Clone, TemplateOnce)]
|
||||||
#[template(path = "index.stpl")] // specify the path to template
|
#[template(path = "index.html")]
|
||||||
struct IndexPage {
|
struct IndexPage {
|
||||||
// data to be passed to the template
|
|
||||||
name: String,
|
name: String,
|
||||||
title: String,
|
title: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for IndexPage {
|
||||||
|
fn default() -> Self {
|
||||||
|
IndexPage {
|
||||||
|
name: "mCaptcha".into(),
|
||||||
|
title: "Login".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexPage {
|
||||||
|
pub async fn run(&self) -> Result<(), Error> {
|
||||||
|
let file = root_path("index.html");
|
||||||
|
|
||||||
|
info!("rendering {}", &file);
|
||||||
|
let index = self.clone().render_once().unwrap();
|
||||||
|
|
||||||
|
fs::write(&file, index).await?;
|
||||||
|
info!("wrote {}", &file);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const BASE_DIR: &str = "./output";
|
const BASE_DIR: &str = "./output";
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
@@ -28,43 +49,132 @@ async fn main() {
|
|||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ctx = IndexPage {
|
IndexPage::default().run().await.unwrap();
|
||||||
name: "mCaptcha".into(),
|
signup::IndexPage::default().run().await.unwrap();
|
||||||
title: "Login".into(),
|
panel::IndexPage::default().run().await.unwrap();
|
||||||
};
|
|
||||||
|
|
||||||
// Now render templates with given data
|
|
||||||
info!("rendering {}", path("index.html"));
|
|
||||||
let index = ctx.render_once().unwrap();
|
|
||||||
fs::write(path("index.html"), index).await.unwrap();
|
|
||||||
info!("wrote {}", path("index.html"));
|
|
||||||
|
|
||||||
let ctx = signup::IndexPage {
|
|
||||||
name: "mCaptcha".into(),
|
|
||||||
title: "Register".into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Now render templates with given data
|
|
||||||
info!("rendering {}", path("signup/index.html"));
|
|
||||||
let index = ctx.render_once().unwrap();
|
|
||||||
fs::create_dir(path("signup")).await.unwrap();
|
|
||||||
info!("creating dir {}", path("signup/"));
|
|
||||||
|
|
||||||
fs::write(path("signup/index.html"), index).await.unwrap();
|
|
||||||
info!("wrote {}", path("signup/index.html"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn path(rel: &str) -> String {
|
fn root_path(rel: &str) -> String {
|
||||||
format!("{}/{}", BASE_DIR, rel)
|
format!("{}/{}", BASE_DIR, rel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rel_path(dir: &str, file: &str) -> String {
|
||||||
|
format!("{}/{}", dir, file)
|
||||||
|
}
|
||||||
|
|
||||||
mod signup {
|
mod signup {
|
||||||
use super::*;
|
use super::*;
|
||||||
#[derive(TemplateOnce)] // automatically implement `TemplateOnce` trait
|
|
||||||
#[template(path = "signup/index.stpl", escape = false)] // specify the path to template
|
#[derive(TemplateOnce, Clone)]
|
||||||
|
#[template(path = "signup/index.html")]
|
||||||
pub struct IndexPage {
|
pub struct IndexPage {
|
||||||
// data to be passed to the template
|
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for IndexPage {
|
||||||
|
fn default() -> Self {
|
||||||
|
IndexPage {
|
||||||
|
name: "mCaptcha".into(),
|
||||||
|
title: "Join".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexPage {
|
||||||
|
pub async fn run(&self) -> Result<(), Error> {
|
||||||
|
let dir = root_path("signup");
|
||||||
|
let file = rel_path(&dir, "index.html");
|
||||||
|
|
||||||
|
print!("");
|
||||||
|
info!("rendering {}", &file);
|
||||||
|
let index = self.clone().render_once().unwrap();
|
||||||
|
|
||||||
|
fs::create_dir(&dir).await?;
|
||||||
|
info!("creating dir {}", &dir);
|
||||||
|
|
||||||
|
fs::write(&file, index).await?;
|
||||||
|
info!("wrote {}", &file);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Literal = &'static str;
|
||||||
|
|
||||||
|
pub mod panel {
|
||||||
|
use super::*;
|
||||||
|
use section::*;
|
||||||
|
|
||||||
|
#[derive(TemplateOnce, Clone)]
|
||||||
|
#[template(path = "panel/index.html")]
|
||||||
|
pub struct IndexPage {
|
||||||
|
pub name: String,
|
||||||
|
pub title: String,
|
||||||
|
pub active: &'static SubPanel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for IndexPage {
|
||||||
|
fn default() -> Self {
|
||||||
|
IndexPage {
|
||||||
|
name: "mCaptcha".into(),
|
||||||
|
title: "Home".into(),
|
||||||
|
active: &COMMENTS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexPage {
|
||||||
|
pub async fn run(&self) -> Result<(), Error> {
|
||||||
|
let dir = root_path("panel");
|
||||||
|
let file = rel_path(&dir, "index.html");
|
||||||
|
|
||||||
|
info!("rendering {}", &file);
|
||||||
|
let index = self.clone().render_once().unwrap();
|
||||||
|
|
||||||
|
fs::create_dir(&dir).await?;
|
||||||
|
info!("creating dir {}", &dir);
|
||||||
|
|
||||||
|
fs::write(&file, index).await?;
|
||||||
|
info!("wrote {}", &file);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod section {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub struct Section<const N: usize> {
|
||||||
|
pub name: Literal,
|
||||||
|
pub elements: [&'static SubPanel; N],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SubPanel {
|
||||||
|
pub name: Literal,
|
||||||
|
pub icon: Literal,
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! sub_panel {
|
||||||
|
($var:ident, $name:expr, $icon:expr) => {
|
||||||
|
pub static $var: SubPanel = SubPanel {
|
||||||
|
name: $name,
|
||||||
|
icon: $icon,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub_panel!(COMMENTS, "Comments", "comments");
|
||||||
|
sub_panel!(USERS, "Users", "users");
|
||||||
|
sub_panel!(PAGES, "Pages", "pages");
|
||||||
|
|
||||||
|
pub static ADMIN_SECTION: Section<3> = Section {
|
||||||
|
elements: [&COMMENTS, &USERS, &PAGES],
|
||||||
|
name: "Admin",
|
||||||
|
};
|
||||||
|
|
||||||
|
pub static SETTINGS_SECTION: Section<3> = Section {
|
||||||
|
elements: [&COMMENTS, &USERS, &PAGES],
|
||||||
|
name: "Settings",
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
frontend/static/img/svg/bell.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bell"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>
|
||||||
|
After Width: | Height: | Size: 321 B |
1
frontend/static/img/svg/credit-card.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-credit-card"><rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect><line x1="1" y1="10" x2="23" y2="10"></line></svg>
|
||||||
|
After Width: | Height: | Size: 329 B |
1
frontend/static/img/svg/eye-off.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye-off"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>
|
||||||
|
After Width: | Height: | Size: 460 B |
1
frontend/static/img/svg/eye.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
|
||||||
|
After Width: | Height: | Size: 316 B |
1
frontend/static/img/svg/file-text.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
|
||||||
|
After Width: | Height: | Size: 473 B |
1
frontend/static/img/svg/file.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg>
|
||||||
|
After Width: | Height: | Size: 337 B |
1
frontend/static/img/svg/filter.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-filter"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon></svg>
|
||||||
|
After Width: | Height: | Size: 290 B |
1
frontend/static/img/svg/github.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-github"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>
|
||||||
|
After Width: | Height: | Size: 528 B |
1
frontend/static/img/svg/globe.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-globe"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 409 B |
1
frontend/static/img/svg/help-circle.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
|
||||||
|
After Width: | Height: | Size: 365 B |
1
frontend/static/img/svg/home.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
|
||||||
|
After Width: | Height: | Size: 332 B |
1
frontend/static/img/svg/log-out.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-log-out"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
|
||||||
|
After Width: | Height: | Size: 367 B |
1
frontend/static/img/svg/menu.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
|
||||||
|
After Width: | Height: | Size: 346 B |
1
frontend/static/img/svg/moon.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 281 B |
1
frontend/static/img/svg/settings.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-settings"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1011 B |
1
frontend/static/img/svg/shield-off.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield-off"><path d="M19.69 14a6.9 6.9 0 0 0 .31-2V5l-8-3-3.16 1.18"></path><path d="M4.73 4.73L4 5v7c0 6 8 10 8 10a20.29 20.29 0 0 0 5.62-4.38"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>
|
||||||
|
After Width: | Height: | Size: 405 B |
1
frontend/static/img/svg/shield.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 279 B |
1
frontend/static/img/svg/tag.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-tag"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path><line x1="7" y1="7" x2="7.01" y2="7"></line></svg>
|
||||||
|
After Width: | Height: | Size: 355 B |
1
frontend/static/img/svg/toggle-left.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-toggle-left"><rect x="1" y="5" width="22" height="14" rx="7" ry="7"></rect><circle cx="8" cy="12" r="3"></circle></svg>
|
||||||
|
After Width: | Height: | Size: 323 B |
1
frontend/static/img/svg/toggle-right.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-toggle-right"><rect x="1" y="5" width="22" height="14" rx="7" ry="7"></rect><circle cx="16" cy="12" r="3"></circle></svg>
|
||||||
|
After Width: | Height: | Size: 325 B |
1
frontend/static/img/svg/user.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>
|
||||||
|
After Width: | Height: | Size: 313 B |
147
frontend/static/js/css/panel/main.scss
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
<style>
|
||||||
|
/* RESET RULES
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
:root {
|
||||||
|
--page-header-bgColor: #242e42;
|
||||||
|
--page-header-bgColor-hover: #1d2636;
|
||||||
|
--page-header-txtColor: #dde9f8;
|
||||||
|
--page-header-headingColor: #7889a4;
|
||||||
|
--page-header-width: 220px;
|
||||||
|
--page-content-bgColor: #f0f1f6;
|
||||||
|
--page-content-txtColor: #171616;
|
||||||
|
--page-content-blockColor: #fff;
|
||||||
|
--white: #fff;
|
||||||
|
--black: #333;
|
||||||
|
--blue: #00b9eb;
|
||||||
|
--red: #ec1848;
|
||||||
|
--border-radius: 4px;
|
||||||
|
--box-shadow: 0 0 10px -2px rgba(0, 0, 0, 0.075);
|
||||||
|
--switch-bgLightModeColor: #87cefa;
|
||||||
|
--switch-sunColor: gold;
|
||||||
|
--switch-moonColor: #f4f4f4;
|
||||||
|
--switch-bgDarkModeColor: #1f1f27;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$nav-width: 220px;
|
||||||
|
$nav-txt-color: #dde9f8;
|
||||||
|
$nav-bg-color: #242e42;
|
||||||
|
|
||||||
|
$page-content-blockColor: #fff;
|
||||||
|
$border-radius: 4px;
|
||||||
|
$black: #333;
|
||||||
|
$white: #fff;
|
||||||
|
|
||||||
|
|
||||||
|
/* HEADER STYLES
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.nav-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
overflow: auto;
|
||||||
|
padding-top: 20px;
|
||||||
|
width: $nav-width;
|
||||||
|
color: $nav-txt-color;
|
||||||
|
background: $nav-bg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav__home-btn {
|
||||||
|
display: block;
|
||||||
|
margin: 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav__logo {
|
||||||
|
max-width: 120px;
|
||||||
|
fill: $white;
|
||||||
|
filter: invert(100%) sepia(0%) saturate(0%) hue-rotate(298deg)
|
||||||
|
brightness(104%) contrast(101%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav__show-menu {
|
||||||
|
display: none;
|
||||||
|
margin-left: 5px;
|
||||||
|
padding: 4px;
|
||||||
|
background: $page-content-blockColor;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav__show-menu-icon {
|
||||||
|
fill: $black;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
margin-top: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu li:nth-last-child(2) {
|
||||||
|
margin-bottom: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu li:last-child {
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu li > * {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu .switcher {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu .menu-heading h3 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 12px;
|
||||||
|
color: var(--page-header-headingColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu svg {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
fill: var(--page-header-txtColor);
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu a,
|
||||||
|
.page-header .admin-menu button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu a:hover,
|
||||||
|
.page-header .admin-menu a:focus,
|
||||||
|
.page-header .admin-menu button:hover,
|
||||||
|
.page-header .admin-menu button:focus {
|
||||||
|
background: var(--page-header-bgColor-hover);
|
||||||
|
color: var(--blue);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu a:hover svg,
|
||||||
|
.page-header .admin-menu a:focus svg,
|
||||||
|
.page-header .admin-menu button:hover svg,
|
||||||
|
.page-header .admin-menu button:focus svg {
|
||||||
|
fill: var(--blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
0
frontend/static/js/css/panel/sidebar/main.css
Normal file
@@ -2,6 +2,7 @@ import './css/forms.scss';
|
|||||||
|
|
||||||
import signin from './auth/signin';
|
import signin from './auth/signin';
|
||||||
import registerUser from './auth/register';
|
import registerUser from './auth/register';
|
||||||
|
import {run as runPanel} from './panel/index';
|
||||||
import {checkUsernameEventHandler} from './auth/userExists';
|
import {checkUsernameEventHandler} from './auth/userExists';
|
||||||
|
|
||||||
if (window.location.pathname == '/') {
|
if (window.location.pathname == '/') {
|
||||||
@@ -12,8 +13,9 @@ if (window.location.pathname == '/') {
|
|||||||
form.addEventListener('submit', registerUser, true);
|
form.addEventListener('submit', registerUser, true);
|
||||||
let username = document.getElementById('username');
|
let username = document.getElementById('username');
|
||||||
username.addEventListener('input', checkUsernameEventHandler, false);
|
username.addEventListener('input', checkUsernameEventHandler, false);
|
||||||
|
} else if (window.location.pathname.includes('panel')) {
|
||||||
|
runPanel();
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//export default signin;
|
//export default signin;
|
||||||
|
|||||||
67
frontend/static/js/panel/index.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
export const run = () => {
|
||||||
|
const html = document.documentElement;
|
||||||
|
const body = document.body;
|
||||||
|
const menuLinks = document.querySelectorAll('.admin-menu a');
|
||||||
|
const collapseBtn = document.querySelector('.admin-menu .collapse-btn');
|
||||||
|
const toggleMobileMenu = document.querySelector('.toggle-mob-menu');
|
||||||
|
const switchInput = document.querySelector('.switch input');
|
||||||
|
const switchLabel = document.querySelector('.switch label');
|
||||||
|
const switchLabelText = switchLabel.querySelector('span:last-child');
|
||||||
|
const collapsedClass = 'collapsed';
|
||||||
|
const lightModeClass = 'light-mode';
|
||||||
|
|
||||||
|
/*TOGGLE HEADER STATE*/
|
||||||
|
collapseBtn.addEventListener('click', function() {
|
||||||
|
body.classList.toggle(collapsedClass);
|
||||||
|
this.getAttribute('aria-expanded') == 'true'
|
||||||
|
? this.setAttribute('aria-expanded', 'false')
|
||||||
|
: this.setAttribute('aria-expanded', 'true');
|
||||||
|
this.getAttribute('aria-label') == 'collapse menu'
|
||||||
|
? this.setAttribute('aria-label', 'expand menu')
|
||||||
|
: this.setAttribute('aria-label', 'collapse menu');
|
||||||
|
});
|
||||||
|
|
||||||
|
/*TOGGLE MOBILE MENU*/
|
||||||
|
toggleMobileMenu.addEventListener('click', function() {
|
||||||
|
body.classList.toggle('mob-menu-opened');
|
||||||
|
this.getAttribute('aria-expanded') == 'true'
|
||||||
|
? this.setAttribute('aria-expanded', 'false')
|
||||||
|
: this.setAttribute('aria-expanded', 'true');
|
||||||
|
this.getAttribute('aria-label') == 'open menu'
|
||||||
|
? this.setAttribute('aria-label', 'close menu')
|
||||||
|
: this.setAttribute('aria-label', 'open menu');
|
||||||
|
});
|
||||||
|
|
||||||
|
/*SHOW TOOLTIP ON MENU LINK HOVER*/
|
||||||
|
for (const link of menuLinks) {
|
||||||
|
link.addEventListener('mouseenter', function() {
|
||||||
|
if (
|
||||||
|
body.classList.contains(collapsedClass) &&
|
||||||
|
window.matchMedia('(min-width: 768px)').matches
|
||||||
|
) {
|
||||||
|
const tooltip = this.querySelector('span').textContent;
|
||||||
|
this.setAttribute('title', tooltip);
|
||||||
|
} else {
|
||||||
|
this.removeAttribute('title');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TOGGLE LIGHT/DARK MODE*/
|
||||||
|
if (localStorage.getItem('dark-mode') === 'false') {
|
||||||
|
html.classList.add(lightModeClass);
|
||||||
|
switchInput.checked = false;
|
||||||
|
switchLabelText.textContent = 'Light';
|
||||||
|
}
|
||||||
|
|
||||||
|
switchInput.addEventListener('input', function() {
|
||||||
|
html.classList.toggle(lightModeClass);
|
||||||
|
if (html.classList.contains(lightModeClass)) {
|
||||||
|
switchLabelText.textContent = 'Light';
|
||||||
|
localStorage.setItem('dark-mode', 'false');
|
||||||
|
} else {
|
||||||
|
switchLabelText.textContent = 'Dark';
|
||||||
|
localStorage.setItem('dark-mode', 'true');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
2
frontend/templates/components/footers.html
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<html lang="en"><head>
|
<html lang="en"><head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title><%= title %>|<%= name %></title>
|
<title><.= title .>|<.= name .></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<% include!("components/headers.stpl"); %>
|
<. include!("components/headers.html"); .>
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
<img src="../static/img/icon-trans.png" class="form__logo" alt="">
|
<img src="../static/img/icon-trans.png" class="form__logo" alt="">
|
||||||
<h2 class="form__brand">Sign in to mCaptcha</h2>
|
<h2 class="form__brand">Sign in to mCaptcha</h2>
|
||||||
48
frontend/templates/panel/index.html
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<. include!("../components/headers.html"); .> <.# include!("svg.html"); .>
|
||||||
|
<. include!("style.html"); .>
|
||||||
|
<. include!("nav/index.html"); .>
|
||||||
|
|
||||||
|
<section class="page-content">
|
||||||
|
<section class="search-and-user">
|
||||||
|
<form>
|
||||||
|
<input type="search" placeholder="Search Pages..." />
|
||||||
|
<button type="submit" aria-label="submit form">
|
||||||
|
<svg aria-hidden="true">
|
||||||
|
<use xlink:href="#search"></use>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<div class="admin-profile">
|
||||||
|
<span class="greeting">Hello admin</span>
|
||||||
|
<div class="notifications">
|
||||||
|
<span class="badge">1</span>
|
||||||
|
<svg>
|
||||||
|
<use xlink:href="#users"></use>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="grid">
|
||||||
|
<article></article>
|
||||||
|
<article></article>
|
||||||
|
<article></article>
|
||||||
|
<article></article>
|
||||||
|
<article></article>
|
||||||
|
<article></article>
|
||||||
|
<article></article>
|
||||||
|
<article></article>
|
||||||
|
</section>
|
||||||
|
<footer class="page-footer">
|
||||||
|
<span>made by </span>
|
||||||
|
<a href="https://georgemartsoukos.com/" target="_blank">
|
||||||
|
<img
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
src="https://assets.codepen.io/162656/george-martsoukos-small-logo.svg"
|
||||||
|
alt="George Martsoukos logo"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<. include!("../components/footers.html"); .>
|
||||||
8
frontend/templates/panel/nav/collapse-nav/index.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<button
|
||||||
|
class="collapse-btn nav__colapse-btn"
|
||||||
|
aria-expanded="true"
|
||||||
|
aria-label="collapse menu"
|
||||||
|
>
|
||||||
|
<.# Include collapse graphics .>
|
||||||
|
Collapse
|
||||||
|
</button>
|
||||||
20
frontend/templates/panel/nav/index.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<header class="page-header nav-container">
|
||||||
|
<nav class="nav">
|
||||||
|
<a href="#0" aria-label="forecastr logo" class="nav__home-btn">
|
||||||
|
<img class="nav__logo" src="/svg/shield.svg" alt="logo" />
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
class="toggle-mob-menu nav__show-menu"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="open menu"
|
||||||
|
>
|
||||||
|
<.# TODO change show-menu icon .>
|
||||||
|
<svg width="20" height="20" class="nav__show-menu-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#down"></use>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<. include!("menu/index.html"); .>
|
||||||
|
<. include!("theme-toggle/index.html"); .>
|
||||||
|
<. include!("collapse-nav/index.html"); .>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
5
frontend/templates/panel/nav/menu/index.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<ul class="menu">
|
||||||
|
<!-- Sections -->
|
||||||
|
<. let section = &ADMIN_SECTION; .> <. include!("section/index.html"); .> <.
|
||||||
|
let section = &SETTINGS_SECTION; .> <. include!("section/index.html"); .>
|
||||||
|
</ul>
|
||||||
3
frontend/templates/panel/nav/menu/section/heading.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<li class="menu-heading nav-menu__heading nav-section__heading">
|
||||||
|
<h3><.= section.name .></h3>
|
||||||
|
</li>
|
||||||
4
frontend/templates/panel/nav/menu/section/index.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<. include!("heading.html"); .>
|
||||||
|
<. for heading in §ion.elements { .>
|
||||||
|
<. include!("item.html"); .>
|
||||||
|
<.}; .>
|
||||||
24
frontend/templates/panel/nav/menu/section/item.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<li
|
||||||
|
class='<.= if active.name == heading.name {"nav-section__item--active"} else { "nav-section__item"} .>'
|
||||||
|
<a href="#0" class="nav-menu__item__link nav-section__item__link">
|
||||||
|
<img
|
||||||
|
class="icon nav-menu__item__icon nav-section__item__icon"
|
||||||
|
src="/svg/<.= heading.icon.>.svg"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<.= heading.name .>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.nav-section__item__link {
|
||||||
|
filter: invert(100%) sepia(0%) saturate(0%) hue-rotate(298deg)
|
||||||
|
brightness(104%) contrast(101%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-section__item:hover {
|
||||||
|
background: var(--page-header-bgColor-hover);
|
||||||
|
color: var(--blue);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
13
frontend/templates/panel/nav/theme-toggle/index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="theme-switch">
|
||||||
|
<input type="checkbox" id="theme-switch_checkbox" class="theme-switch__checkbox" checked />
|
||||||
|
<label for="theme-switch__checkbox">
|
||||||
|
<span></span>
|
||||||
|
<span class="theme-switch__dark>Dark</span>
|
||||||
|
<span class="theme-switch__light>Dark</span>
|
||||||
|
</label>
|
||||||
|
<style>
|
||||||
|
.theme-switch__light {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</div>
|
||||||
559
frontend/templates/panel/style.html
Normal file
@@ -0,0 +1,559 @@
|
|||||||
|
<style>
|
||||||
|
/* RESET RULES
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
@import url('https://fonts.googleapis.com/css?family=Lato:400,700&display=swap');
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--page-header-bgColor: #242e42;
|
||||||
|
--page-header-bgColor-hover: #1d2636;
|
||||||
|
--page-header-txtColor: #dde9f8;
|
||||||
|
--page-header-headingColor: #7889a4;
|
||||||
|
--page-header-width: 220px;
|
||||||
|
--page-content-bgColor: #f0f1f6;
|
||||||
|
--page-content-txtColor: #171616;
|
||||||
|
--page-content-blockColor: #fff;
|
||||||
|
--white: #fff;
|
||||||
|
--black: #333;
|
||||||
|
--blue: #00b9eb;
|
||||||
|
--red: #ec1848;
|
||||||
|
--border-radius: 4px;
|
||||||
|
--box-shadow: 0 0 10px -2px rgba(0, 0, 0, 0.075);
|
||||||
|
--switch-bgLightModeColor: #87cefa;
|
||||||
|
--switch-sunColor: gold;
|
||||||
|
--switch-moonColor: #f4f4f4;
|
||||||
|
--switch-bgDarkModeColor: #1f1f27;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
button {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type='checkbox'] {
|
||||||
|
position: absolute;
|
||||||
|
left: -9999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
input {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font: 16px/1.5 'Lato', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HEADER STYLES
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.page-header,
|
||||||
|
.nav-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
overflow: auto;
|
||||||
|
padding-top: 20px;
|
||||||
|
width: var(--page-header-width);
|
||||||
|
color: var(--page-header-txtColor);
|
||||||
|
background: var(--page-header-bgColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*In case you prefer an absolutely positioned header that covers the full page height, add these styles*/
|
||||||
|
/*body {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
.nav {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav__home-btn {
|
||||||
|
display: block;
|
||||||
|
margin: 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav__logo {
|
||||||
|
max-width: 120px;
|
||||||
|
fill: var(--white);
|
||||||
|
filter: invert(100%) sepia(0%) saturate(0%) hue-rotate(298deg)
|
||||||
|
brightness(104%) contrast(101%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .toggle-mob-menu,
|
||||||
|
nav__show-menu {
|
||||||
|
display: none;
|
||||||
|
margin-left: 5px;
|
||||||
|
padding: 4px;
|
||||||
|
background: var(--page-content-blockColor);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .toggle-mob-menu svg,
|
||||||
|
nav__show-menu-icon {
|
||||||
|
fill: var(--black);
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
margin-top: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu li:nth-last-child(2) {
|
||||||
|
margin-bottom: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu li:last-child {
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu li > * {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu .switcher {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu .menu-heading h3 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 12px;
|
||||||
|
color: var(--page-header-headingColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu svg {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
fill: var(--page-header-txtColor);
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu a,
|
||||||
|
.page-header .admin-menu button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu a:hover,
|
||||||
|
.page-header .admin-menu a:focus,
|
||||||
|
.page-header .admin-menu button:hover,
|
||||||
|
.page-header .admin-menu button:focus {
|
||||||
|
background: var(--page-header-bgColor-hover);
|
||||||
|
color: var(--blue);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu a:hover svg,
|
||||||
|
.page-header .admin-menu a:focus svg,
|
||||||
|
.page-header .admin-menu button:hover svg,
|
||||||
|
.page-header .admin-menu button:focus svg {
|
||||||
|
fill: var(--blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PAGE CONTENT STYLES
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.page-content {
|
||||||
|
position: relative;
|
||||||
|
left: var(--page-header-width);
|
||||||
|
width: calc(100% - var(--page-header-width));
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 30px;
|
||||||
|
color: var(--page-content-txtColor);
|
||||||
|
background: var(--page-content-bgColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
grid-column-gap: 50px;
|
||||||
|
align-items: center;
|
||||||
|
background: var(--page-content-bgColor);
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user form {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user [type='search'] {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
padding-left: 15px;
|
||||||
|
background: var(--page-content-blockColor);
|
||||||
|
color: var(--white);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
box-shadow: var(--box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user ::placeholder {
|
||||||
|
color: var(--page-content-txtColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user form svg {
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
fill: var(--page-content-txtColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user form button {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 15px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user .admin-profile {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user .admin-profile .greeting {
|
||||||
|
margin: 0 10px 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user .admin-profile svg {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user .admin-profile .notifications {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user .admin-profile .badge {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
top: -10px;
|
||||||
|
right: -3px;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 10px;
|
||||||
|
color: var(--white);
|
||||||
|
background: var(--red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content .grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content .grid > article {
|
||||||
|
display: flex;
|
||||||
|
height: 300px;
|
||||||
|
background: var(--page-content-blockColor);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
box-shadow: var(--box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content .grid > article:first-child,
|
||||||
|
.page-content .grid > article:last-child {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MQ RULES
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.page-header,
|
||||||
|
.page-content {
|
||||||
|
position: static;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header nav {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .logo {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .logo svg {
|
||||||
|
width: 83px;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .toggle-mob-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu {
|
||||||
|
position: absolute;
|
||||||
|
left: 98px;
|
||||||
|
top: 57px;
|
||||||
|
margin-top: 0;
|
||||||
|
z-index: 2;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
background: var(--page-header-bgColor);
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.95);
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu li:nth-last-child(2) {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .admin-menu li:last-child button,
|
||||||
|
.search-and-user .admin-profile .greeting {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content {
|
||||||
|
min-height: 0;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content .grid {
|
||||||
|
grid-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user {
|
||||||
|
position: absolute;
|
||||||
|
left: 131px;
|
||||||
|
top: 10px;
|
||||||
|
padding: 0;
|
||||||
|
grid-column-gap: 5px;
|
||||||
|
width: calc(100% - 141px);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user [type='search'] {
|
||||||
|
font-size: 1rem;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user form svg {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-and-user .admin-profile svg {
|
||||||
|
fill: var(--white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 400px) {
|
||||||
|
.page-content .grid > article {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BODY CLASSES
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.mob-menu-opened .toggle-mob-menu svg {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mob-menu-opened .page-header .admin-menu {
|
||||||
|
transform: scale(1);
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.collapsed .page-header {
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed .page-header .admin-menu li > * {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed .page-header .logo,
|
||||||
|
.collapsed .page-header .admin-menu span,
|
||||||
|
.collapsed .page-header .admin-menu .menu-heading {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed .page-header .admin-menu svg {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed .page-header .collapse-btn svg {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed .page-content {
|
||||||
|
left: 40px;
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SWITCH STYLES
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.switch label {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto;
|
||||||
|
grid-column-gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch span:first-child {
|
||||||
|
position: relative;
|
||||||
|
width: 50px;
|
||||||
|
height: 26px;
|
||||||
|
border-radius: 15px;
|
||||||
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.4);
|
||||||
|
background: var(--switch-bgLightModeColor);
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch span:first-child::before,
|
||||||
|
.switch span:first-child::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch span:first-child::before {
|
||||||
|
top: 1px;
|
||||||
|
left: 1px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background: var(--white);
|
||||||
|
z-index: 1;
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch span:first-child::after {
|
||||||
|
top: 50%;
|
||||||
|
right: 8px;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
background: var(--switch-sunColor);
|
||||||
|
box-shadow: 0 0 4px 2px #ffdb1a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch [type='checkbox']:checked + label span:first-child {
|
||||||
|
background: var(--switch-bgDarkModeColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch [type='checkbox']:focus + label span:first-child {
|
||||||
|
box-shadow: 0 3px 5px rgba(255, 255, 255, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch [type='checkbox']:checked + label span:first-child::before {
|
||||||
|
transform: translateX(24px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch [type='checkbox']:checked + label span:first-child::after {
|
||||||
|
left: 12px;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: -2px -5px 0 var(--switch-moonColor);
|
||||||
|
transform: translateY(-50%) rotate(-72deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LIGHT MODE STYLES
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.light-mode {
|
||||||
|
--page-header-bgColor: #f1efec;
|
||||||
|
--page-header-bgColor-hover: #b9e4e0;
|
||||||
|
--page-header-txtColor: #2c303a;
|
||||||
|
--page-header-headingColor: #979595;
|
||||||
|
--page-content-bgColor: #fff;
|
||||||
|
--box-shadow: 0 0 10px -2px rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.light-mode .page-header .admin-menu a:hover,
|
||||||
|
.light-mode .page-header .admin-menu a:focus,
|
||||||
|
.light-mode .page-header .admin-menu button:hover,
|
||||||
|
.light-mode .page-header .admin-menu button:focus {
|
||||||
|
color: var(--black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.light-mode .page-header .logo svg,
|
||||||
|
.light-mode .page-header .admin-menu a:hover svg,
|
||||||
|
.light-mode .page-header .admin-menu a:focus svg,
|
||||||
|
.light-mode .page-header .admin-menu button:hover svg,
|
||||||
|
.light-mode .page-header .admin-menu button:focus svg {
|
||||||
|
fill: var(--black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.light-mode .switch [type='checkbox']:focus + label span:first-child {
|
||||||
|
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.light-mode .search-and-user .admin-profile svg {
|
||||||
|
fill: var(--black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FOOTER
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.page-footer {
|
||||||
|
font-size: 1rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-footer a {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
65
frontend/templates/signup/index.html
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<. include!("../components/headers.html"); .>
|
||||||
|
<div class="form-container">
|
||||||
|
<img src="/static/img/icon-trans.png" class="form__logo" alt="" />
|
||||||
|
<h2 class="form__brand">Join mCaptcha</h2>
|
||||||
|
|
||||||
|
<form class="form__box" id="form">
|
||||||
|
<label class="form__in-group" for="username"
|
||||||
|
>Username
|
||||||
|
<input
|
||||||
|
class="form__in-field"
|
||||||
|
id="username"
|
||||||
|
type="text"
|
||||||
|
name="username"
|
||||||
|
id="username"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="form__in-group" for="username"
|
||||||
|
>Email
|
||||||
|
<input
|
||||||
|
class="form__in-field"
|
||||||
|
id="email"
|
||||||
|
type="email"
|
||||||
|
name="email"
|
||||||
|
id="email"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label for="password" class="form__in-group"
|
||||||
|
>Password
|
||||||
|
<input
|
||||||
|
class="form__in-field"
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
id="password"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label for="password" class="form__in-group"
|
||||||
|
>Re-enter Password
|
||||||
|
<input
|
||||||
|
class="form__in-field"
|
||||||
|
type="password"
|
||||||
|
id="password-check"
|
||||||
|
name="password-check"
|
||||||
|
id="password-check"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<button class="form__submit-button" type="submit">
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<div class="form__secondary-action">
|
||||||
|
<p class="form__secondary-action__banner">
|
||||||
|
New to mCaptcha?
|
||||||
|
<a href="/" class="form__secondary-action__link">Create account</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<. include!("../components/footers.html"); .>
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<% include!("../components/headers.stpl"); %>
|
|
||||||
<body>
|
|
||||||
<div class="form-container">
|
|
||||||
<img src="../../static/img/icon-trans.png" class="form__logo" alt="">
|
|
||||||
<h2 class="form__brand">Join mCaptcha</h2>
|
|
||||||
|
|
||||||
<form class="form__box" id="form">
|
|
||||||
<label class="form__in-group" for="username">Username
|
|
||||||
<input class="form__in-field" id="username" type="text" name="username" required="">
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label for="password" class="form__in-group">Password
|
|
||||||
<input class="form__in-field" type="password" id="password" name="password" required="">
|
|
||||||
<!--
|
|
||||||
<a class="form__pw-recovery" -href="/recovert/password"
|
|
||||||
>Forgot password?</a
|
|
||||||
>
|
|
||||||
-->
|
|
||||||
</label>
|
|
||||||
<button class="form__submit-button" type="submit">
|
|
||||||
Submit
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<div class="form__secondary-action">
|
|
||||||
<p class="form__secondary-action__banner">
|
|
||||||
New to mCaptcha?
|
|
||||||
<a href="/signup" class="form__secondary-action__link">Create account</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body></html>
|
|
||||||
@@ -1,34 +1,38 @@
|
|||||||
const path = require("path");
|
const path = require('path');
|
||||||
const common = require("./webpack.common");
|
const common = require('./webpack.common');
|
||||||
const merge = require("webpack-merge");
|
const merge = require('webpack-merge');
|
||||||
var HtmlWebpackPlugin = require("html-webpack-plugin");
|
var HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
|
||||||
module.exports = merge(common, {
|
module.exports = merge(common, {
|
||||||
mode: "development",
|
mode: 'development',
|
||||||
output: {
|
output: {
|
||||||
filename: "[name].bundle.js",
|
filename: '[name].bundle.js',
|
||||||
path: path.resolve(__dirname, "dist")
|
path: path.resolve(__dirname, 'dist'),
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: "./output/index.html"
|
template: './output/index.html',
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
filename: "signup/index.html",
|
filename: 'signup/index.html',
|
||||||
template: "./output/signup/index.html"
|
template: './output/signup/index.html',
|
||||||
})
|
}),
|
||||||
|
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
filename: 'panel/index.html',
|
||||||
|
template: './output/panel/index.html',
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.scss$/,
|
test: /\.scss$/,
|
||||||
use: [
|
use: [
|
||||||
"style-loader", //3. Inject styles into DOM
|
'style-loader', //3. Inject styles into DOM
|
||||||
"css-loader", //2. Turns css into commonjs
|
'css-loader', //2. Turns css into commonjs
|
||||||
"sass-loader" //1. Turns sass into css
|
'sass-loader', //1. Turns sass into css
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ module.exports = merge(common, {
|
|||||||
removeComments: true,
|
removeComments: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
filename: 'panel/index.html',
|
||||||
|
template: './output/panel/index.html',
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
|||||||
@@ -1,817 +0,0 @@
|
|||||||
{
|
|
||||||
"info": {
|
|
||||||
"_postman_id": "75a16c22-17aa-43ca-8906-0cc33844f77e",
|
|
||||||
"name": "mCaptcha/guard",
|
|
||||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
|
||||||
},
|
|
||||||
"item": [
|
|
||||||
{
|
|
||||||
"name": "api/v1",
|
|
||||||
"item": [
|
|
||||||
{
|
|
||||||
"name": "account",
|
|
||||||
"item": [
|
|
||||||
{
|
|
||||||
"name": "Delete user account",
|
|
||||||
"request": {
|
|
||||||
"auth": {
|
|
||||||
"type": "apikey",
|
|
||||||
"apikey": [
|
|
||||||
{
|
|
||||||
"key": "key",
|
|
||||||
"value": "Authorization",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "value",
|
|
||||||
"value": true,
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "in",
|
|
||||||
"value": "header",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"password\": \"dolor aliquip laboris id\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/delete",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"delete"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"response": [
|
|
||||||
{
|
|
||||||
"name": "OK",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"description": {
|
|
||||||
"content": "Added as a part of security scheme: apikey",
|
|
||||||
"type": "text/plain"
|
|
||||||
},
|
|
||||||
"key": "Authorization",
|
|
||||||
"value": "<API Key>"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"password\": \"dolor aliquip laboris id\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/delete",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"delete"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "OK",
|
|
||||||
"code": 200,
|
|
||||||
"_postman_previewlanguage": "text",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "text/plain"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "(cookie)authentication required or wrong password",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"description": {
|
|
||||||
"content": "Added as a part of security scheme: apikey",
|
|
||||||
"type": "text/plain"
|
|
||||||
},
|
|
||||||
"key": "Authorization",
|
|
||||||
"value": "<API Key>"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"password\": \"dolor aliquip laboris id\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/delete",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"delete"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Unauthorized",
|
|
||||||
"code": 401,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "username not found",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"description": {
|
|
||||||
"content": "Added as a part of security scheme: apikey",
|
|
||||||
"type": "text/plain"
|
|
||||||
},
|
|
||||||
"key": "Authorization",
|
|
||||||
"value": "<API Key>"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"password\": \"dolor aliquip laboris id\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/delete",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"delete"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Not Found",
|
|
||||||
"code": 404,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Internal server error",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"description": {
|
|
||||||
"content": "Added as a part of security scheme: apikey",
|
|
||||||
"type": "text/plain"
|
|
||||||
},
|
|
||||||
"key": "Authorization",
|
|
||||||
"value": "<API Key>"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"password\": \"dolor aliquip laboris id\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/delete",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"delete"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Internal Server Error",
|
|
||||||
"code": 500,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Check if username exists",
|
|
||||||
"request": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"val\": \"eiusmod irure s\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/username/exists",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"username",
|
|
||||||
"exists"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"response": [
|
|
||||||
{
|
|
||||||
"name": "OK",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"val\": \"eiusmod irure s\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/username/exists",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"username",
|
|
||||||
"exists"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "OK",
|
|
||||||
"code": 200,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"val\": false\n}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Internal server error",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"val\": \"eiusmod irure s\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/username/exists",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"username",
|
|
||||||
"exists"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Internal Server Error",
|
|
||||||
"code": 500,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Check if email exists",
|
|
||||||
"request": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"val\": \"eiusmod irure s\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/email/exists",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"email",
|
|
||||||
"exists"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"response": [
|
|
||||||
{
|
|
||||||
"name": "OK",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"val\": \"eiusmod irure s\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/email/exists",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"email",
|
|
||||||
"exists"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "OK",
|
|
||||||
"code": 200,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"val\": false\n}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Internal server error",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"val\": \"eiusmod irure s\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/account/email/exists",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"account",
|
|
||||||
"email",
|
|
||||||
"exists"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Internal Server Error",
|
|
||||||
"code": 500,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Registration endpoint",
|
|
||||||
"request": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"username\": \"adipisicing\",\n \"password\": \"quis ut ipsum culpa\",\n \"email\": \"fugiat dolor ullamco magna\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signup",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signup"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"response": [
|
|
||||||
{
|
|
||||||
"name": "Bad request: username contains profainity/blacklisted words or email not acceptable or password too long/short or duplicate username/password",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"username\": \"adipisicing\",\n \"password\": \"quis ut ipsum culpa\",\n \"email\": \"fugiat dolor ullamco magna\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signup",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signup"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Bad Request",
|
|
||||||
"code": 400,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Successful registration",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"username\": \"adipisicing\",\n \"password\": \"quis ut ipsum culpa\",\n \"email\": \"fugiat dolor ullamco magna\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signup",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signup"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "OK",
|
|
||||||
"code": 200,
|
|
||||||
"_postman_previewlanguage": "text",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "text/plain"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Internal server error",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"username\": \"adipisicing\",\n \"password\": \"quis ut ipsum culpa\",\n \"email\": \"fugiat dolor ullamco magna\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signup",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signup"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Internal Server Error",
|
|
||||||
"code": 500,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Login endpoint",
|
|
||||||
"request": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"username\": \"voluptate proident nulla cupidatat do\",\n \"password\": \"sint ut commodo\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signin",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signin"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"response": [
|
|
||||||
{
|
|
||||||
"name": "Successful authentication",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"username\": \"voluptate proident nulla cupidatat do\",\n \"password\": \"sint ut commodo\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signin",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signin"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "OK",
|
|
||||||
"code": 200,
|
|
||||||
"_postman_previewlanguage": "text",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "text/plain"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Internal server error",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"username\": \"voluptate proident nulla cupidatat do\",\n \"password\": \"sint ut commodo\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signin",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signin"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Internal Server Error",
|
|
||||||
"code": 500,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "username not found",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"username\": \"voluptate proident nulla cupidatat do\",\n \"password\": \"sint ut commodo\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signin",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signin"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Not Found",
|
|
||||||
"code": 404,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "authentication failed, wrong password",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"body": {
|
|
||||||
"mode": "raw",
|
|
||||||
"raw": "{\n \"username\": \"voluptate proident nulla cupidatat do\",\n \"password\": \"sint ut commodo\"\n}"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signin",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signin"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "Unauthorized",
|
|
||||||
"code": 401,
|
|
||||||
"_postman_previewlanguage": "json",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "application/json"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": "{\n \"error\": \"elit enim fugiat\"\n}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Signout endpoint",
|
|
||||||
"request": {
|
|
||||||
"auth": {
|
|
||||||
"type": "apikey",
|
|
||||||
"apikey": [
|
|
||||||
{
|
|
||||||
"key": "key",
|
|
||||||
"value": "Authorization",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "value",
|
|
||||||
"value": true,
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "in",
|
|
||||||
"value": "header",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"method": "POST",
|
|
||||||
"header": [],
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signout",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signout"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"response": [
|
|
||||||
{
|
|
||||||
"name": "OK",
|
|
||||||
"originalRequest": {
|
|
||||||
"method": "POST",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"description": {
|
|
||||||
"content": "Added as a part of security scheme: apikey",
|
|
||||||
"type": "text/plain"
|
|
||||||
},
|
|
||||||
"key": "Authorization",
|
|
||||||
"value": "<API Key>"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"url": {
|
|
||||||
"raw": "{{baseUrl}}/api/v1/signout",
|
|
||||||
"host": [
|
|
||||||
"{{baseUrl}}"
|
|
||||||
],
|
|
||||||
"path": [
|
|
||||||
"api",
|
|
||||||
"v1",
|
|
||||||
"signout"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"status": "OK",
|
|
||||||
"code": 200,
|
|
||||||
"_postman_previewlanguage": "text",
|
|
||||||
"header": [
|
|
||||||
{
|
|
||||||
"key": "Content-Type",
|
|
||||||
"value": "text/plain"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cookie": [],
|
|
||||||
"body": ""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"variable": [
|
|
||||||
{
|
|
||||||
"key": "baseUrl",
|
|
||||||
"value": "http://localhost:3000",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
<% include!("./top.stpl"); %>
|
<. include!("./top.html"); .>
|
||||||
|
|
||||||
<title>Sign in | mCaptcha</title>
|
<title>Sign in | mCaptcha</title>
|
||||||
<img src="./img/icon-trans.png" class="form__logo" alt="" />
|
<img src="./img/icon-trans.png" class="form__logo" alt="" />
|
||||||
<h2 class="form__brand">Sign in to mCaptcha</h2>
|
<h2 class="form__brand">Sign in to mCaptcha</h2>
|
||||||
|
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
<form class="form__box">
|
<form class="form__box">
|
||||||
<label class="form__in-group" for="username"
|
<label class="form__in-group" for="username"
|
||||||
@@ -26,113 +25,17 @@
|
|||||||
id="password"
|
id="password"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<a class="form__pw-recovery" -href="/forgot/password"
|
<a class="form__pw-recovery" -href="/forgot/password">Forgot password?</a>
|
||||||
>Forgot password?</a
|
|
||||||
>
|
|
||||||
</label>
|
</label>
|
||||||
<button class="form__submit-button" type="submit">
|
<button class="form__submit-button" type="submit">
|
||||||
Submit
|
Submit
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<div class="form__secondary-action">
|
<div class="form__secondary-action">
|
||||||
<p class="form__secondary-action__banner">New to mCaptcha? <a href="/signup" class="form__secondary-action__link">Create account</a></p>
|
<p class="form__secondary-action__banner">
|
||||||
|
New to mCaptcha?
|
||||||
|
<a href="/" class="form__secondary-action__link">Create account</a>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
<. include!("./bottom.html"); .>
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form__logo {
|
|
||||||
width: 120px;
|
|
||||||
padding-top: 50px;
|
|
||||||
display: block;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form__brand {
|
|
||||||
padding: 10px 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.form-container {
|
|
||||||
max-width: 40%;
|
|
||||||
min-width: 20%;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -49.9%);
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: auto;
|
|
||||||
padding: 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form__box {
|
|
||||||
border: 1px solid #eaecef;
|
|
||||||
background-color: #f6f8fa;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form__in-group {
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
margin: auto;
|
|
||||||
max-width: 80%;
|
|
||||||
padding: 10px 0px;
|
|
||||||
|
|
||||||
box-sizing: content-box;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form__in-field {
|
|
||||||
display: block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 10px 0;
|
|
||||||
padding: 10px 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form__pw-recovery {
|
|
||||||
text-decoration: none;
|
|
||||||
color: rgb(3, 102, 214);
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form__submit-button {
|
|
||||||
display: block;
|
|
||||||
border: 1px solid skyblue;
|
|
||||||
background: #2ea44f;
|
|
||||||
color: white;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 80%;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.form__secondary-action {
|
|
||||||
display: block;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form__secondary-action__banner {
|
|
||||||
display: block;
|
|
||||||
margin: auto;
|
|
||||||
max-width: 80%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form__secondary-action__link{
|
|
||||||
text-decoration: none;
|
|
||||||
color: rgb(3, 102, 214);
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<% include!("./bottom.stpl"); %>
|
|
||||||
|
|||||||