mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2026-02-12 10:35:39 +00:00
frontend templating
This commit is contained in:
@@ -1,47 +0,0 @@
|
||||
const ROUTES = {
|
||||
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',
|
||||
};
|
||||
|
||||
export default ROUTES;
|
||||
@@ -1,43 +0,0 @@
|
||||
import ROUTES from '../api/v1/routes';
|
||||
|
||||
import genJsonPayload from '../utils/genJsonPayload';
|
||||
|
||||
const checkEmailExists = async () => {
|
||||
let email = document.getElementById('email');
|
||||
let val = email.value;
|
||||
let payload = {
|
||||
val,
|
||||
};
|
||||
|
||||
// return fetch(ROUTES.emailExists, genJsonPayload(payload)).then(res => {
|
||||
// if (res.ok) {
|
||||
// res.json().then(data => {
|
||||
// if (data.exists) {
|
||||
// console.log(email.className);
|
||||
// email.className += ' form__in-field--warn';
|
||||
// alert('Email taken');
|
||||
// }
|
||||
//
|
||||
// return data.exists;
|
||||
// });
|
||||
// } else {
|
||||
// res.json().then(err => alert(`error: ${err.error}`));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
|
||||
let res = await fetch(ROUTES.emailExists, genJsonPayload(payload));
|
||||
if (res.ok) {
|
||||
let data = await res.json();
|
||||
if (data.exists) {
|
||||
email.className += ' form__in-field--warn';
|
||||
alert('Email taken');
|
||||
}
|
||||
return data.exists;
|
||||
} else {
|
||||
let err = await res.json();
|
||||
alert(`error: ${err.error}`);
|
||||
}
|
||||
};
|
||||
|
||||
export {checkEmailExists};
|
||||
@@ -1,49 +0,0 @@
|
||||
import ROUTES from '../api/v1/routes';
|
||||
|
||||
import isBlankString from '../utils/isBlankString';
|
||||
import genJsonPayload from '../utils/genJsonPayload';
|
||||
|
||||
import {checkUsernameExists} from './userExists';
|
||||
import {checkEmailExists} from './emailExists';
|
||||
|
||||
const registerUser = async e => {
|
||||
e.preventDefault();
|
||||
|
||||
let username = document.getElementById('username').value;
|
||||
isBlankString(e, username, 'username');
|
||||
|
||||
let password = document.getElementById('password').value;
|
||||
let passwordCheck = document.getElementById('password-check').value;
|
||||
if (password != passwordCheck) {
|
||||
return alert("passwords don't match, check again!");
|
||||
}
|
||||
|
||||
let email = document.getElementById('email').value;
|
||||
isBlankString(e, email, 'email');
|
||||
|
||||
let exists = await checkUsernameExists();
|
||||
if (exists) {
|
||||
return;
|
||||
}
|
||||
|
||||
exists = await checkEmailExists();
|
||||
if (exists) {
|
||||
return;
|
||||
}
|
||||
|
||||
let payload = {
|
||||
username,
|
||||
password,
|
||||
email,
|
||||
};
|
||||
|
||||
let res = await fetch(ROUTES.registerUser, genJsonPayload(payload));
|
||||
if (res.ok) {
|
||||
alert('success');
|
||||
} else {
|
||||
let err = await res.json();
|
||||
alert(`error: ${err.error}`);
|
||||
}
|
||||
};
|
||||
|
||||
export default registerUser;
|
||||
@@ -1,26 +0,0 @@
|
||||
import isBlankString from '../utils/isBlankString';
|
||||
import genJsonPayload from '../utils/genJsonPayload';
|
||||
|
||||
import ROUTES from '../api/v1/routes';
|
||||
|
||||
const signin = e => {
|
||||
e.preventDefault();
|
||||
let username = document.getElementById('username').value;
|
||||
isBlankString(e, username, 'username');
|
||||
|
||||
let password = document.getElementById('password').value;
|
||||
let payload = {
|
||||
username,
|
||||
password,
|
||||
};
|
||||
|
||||
fetch(ROUTES.loginUser, genJsonPayload(payload)).then(res => {
|
||||
if (res.ok) {
|
||||
alert('success');
|
||||
} else {
|
||||
res.json().then(err => alert(`error: ${err.error}`));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default signin;
|
||||
@@ -1,47 +0,0 @@
|
||||
import ROUTES from '../api/v1/routes';
|
||||
|
||||
import genJsonPayload from '../utils/genJsonPayload';
|
||||
|
||||
const checkUsernameEventHandler = _e => {
|
||||
checkUsernameExists();
|
||||
};
|
||||
|
||||
//export const checkUsernameExists = async () => {
|
||||
async function checkUsernameExists() {
|
||||
let username = document.getElementById('username');
|
||||
let val = username.value;
|
||||
let payload = {
|
||||
val,
|
||||
};
|
||||
|
||||
// return fetch(ROUTES.usernameExists, genJsonPayload(payload)).then(res => {
|
||||
// if (res.ok) {
|
||||
// res.json().then(data => {
|
||||
// if (data.exists) {
|
||||
// username.className += ' form__in-field--warn';
|
||||
// alert('Username taken');
|
||||
// }
|
||||
// return data.exists;
|
||||
// });
|
||||
// } else {
|
||||
// res.json().then(err => alert(`error: ${err.error}`));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
|
||||
let res = await fetch(ROUTES.usernameExists, genJsonPayload(payload));
|
||||
if (res.ok) {
|
||||
let data = await res.json();
|
||||
if (data.exists) {
|
||||
username.className += ' form__in-field--warn';
|
||||
alert('Username taken');
|
||||
}
|
||||
return data.exists;
|
||||
} else {
|
||||
let err = await res.json();
|
||||
alert(`error: ${err.error}`);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export {checkUsernameExists, checkUsernameEventHandler};
|
||||
@@ -1,104 +0,0 @@
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.form__logo {
|
||||
width: 110px;
|
||||
padding-top: 50px;
|
||||
display: block;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
top: 20%;
|
||||
transform: translate(0%, -40.9%);
|
||||
}
|
||||
|
||||
.form__brand {
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: 20%;
|
||||
transform: translate(0%, -90.9%);
|
||||
}
|
||||
|
||||
.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__in-field--warn {
|
||||
border: solid 1px red;
|
||||
}
|
||||
|
||||
.form__in-field--success {
|
||||
border: solid 1px #2ea44f;
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import './css/forms.scss';
|
||||
|
||||
import signin from './auth/signin';
|
||||
import registerUser from './auth/register';
|
||||
import {checkUsernameEventHandler} from './auth/userExists';
|
||||
|
||||
if (window.location.pathname == '/') {
|
||||
let form = document.getElementById('form');
|
||||
form.addEventListener('submit', signin, true);
|
||||
} else if (window.location.pathname == '/signup') {
|
||||
let form = document.getElementById('form');
|
||||
form.addEventListener('submit', registerUser, true);
|
||||
let username = document.getElementById('username');
|
||||
username.addEventListener('input', checkUsernameEventHandler, false);
|
||||
} else {
|
||||
}
|
||||
|
||||
|
||||
//export default signin;
|
||||
70
frontend/src/main.rs
Normal file
70
frontend/src/main.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use log::{debug, info};
|
||||
use sailfish::TemplateOnce;
|
||||
use tokio::fs;
|
||||
use tokio::io::{Error, ErrorKind};
|
||||
|
||||
#[derive(TemplateOnce)] // automatically implement `TemplateOnce` trait
|
||||
#[template(path = "index.stpl")] // specify the path to template
|
||||
struct IndexPage {
|
||||
// data to be passed to the template
|
||||
name: String,
|
||||
title: String,
|
||||
}
|
||||
|
||||
const BASE_DIR: &str = "./output";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
pretty_env_logger::init();
|
||||
match fs::create_dir(BASE_DIR).await {
|
||||
Err(e) => {
|
||||
if e.kind() == ErrorKind::AlreadyExists {
|
||||
info!("cleaning up old assetes");
|
||||
fs::remove_dir_all(BASE_DIR).await.unwrap();
|
||||
debug!("creating target location");
|
||||
fs::create_dir(BASE_DIR).await.unwrap();
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
|
||||
let ctx = IndexPage {
|
||||
name: "mCaptcha".into(),
|
||||
title: "Login".into(),
|
||||
};
|
||||
|
||||
// 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 {
|
||||
format!("{}/{}", BASE_DIR, rel)
|
||||
}
|
||||
|
||||
mod signup {
|
||||
use super::*;
|
||||
#[derive(TemplateOnce)] // automatically implement `TemplateOnce` trait
|
||||
#[template(path = "signup/index.stpl", escape = false)] // specify the path to template
|
||||
pub struct IndexPage {
|
||||
// data to be passed to the template
|
||||
pub name: String,
|
||||
pub title: String,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import './css/forms.scss';
|
||||
import registerUser from './auth/register';
|
||||
|
||||
let form = document.getElementById('form');
|
||||
form.addEventListener('submit', registerUser, true);
|
||||
|
||||
let username = document.getElementById('username');
|
||||
username.addEventListener('input', checkUsernameEventHandler, false);
|
||||
@@ -1,12 +0,0 @@
|
||||
const genJsonPayload = payload => {
|
||||
let value = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
};
|
||||
return value;
|
||||
};
|
||||
|
||||
export default genJsonPayload;
|
||||
@@ -1,8 +0,0 @@
|
||||
const isBlankString = (event, value, field) => {
|
||||
if (!value.replace(/\s/g, '').length) {
|
||||
event.preventDefault();
|
||||
alert(`${field} can't be empty`);
|
||||
}
|
||||
};
|
||||
|
||||
export default isBlankString;
|
||||
Reference in New Issue
Block a user