mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2026-02-11 10:05:41 +00:00
list sitekey: copy sitekey
This commit is contained in:
11
Cargo.lock
generated
11
Cargo.lock
generated
@@ -1588,6 +1588,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
|
"openssl",
|
||||||
"pow_sha256",
|
"pow_sha256",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"rand 0.8.4",
|
"rand 0.8.4",
|
||||||
@@ -1873,6 +1874,15 @@ version = "0.1.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl-src"
|
||||||
|
version = "111.15.0+1.1.1k"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1a5f6ae2ac04393b217ea9f700cd04fa9bf3d93fae2872069f3d15d908af70a"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.65"
|
version = "0.9.65"
|
||||||
@@ -1882,6 +1892,7 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
|
"openssl-src",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ lettre = { version = "0.10.0-rc.3", features = [
|
|||||||
"smtp-transport"
|
"smtp-transport"
|
||||||
]}
|
]}
|
||||||
|
|
||||||
|
openssl = { version = "0.10.29", features = ["vendored"] }
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde_yaml = "0.8.17"
|
serde_yaml = "0.8.17"
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ pub mod routes {
|
|||||||
impl Sitekey {
|
impl Sitekey {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Sitekey {
|
Sitekey {
|
||||||
list: "/sitekey/list",
|
list: "/sitekeys",
|
||||||
add: "/sitekey/add",
|
add: "/sitekeys/add",
|
||||||
view: "/sitekey/{key}",
|
view: "/sitekey/{key}",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
static/cache/img/svg/clipboard.svg
vendored
Normal file
1
static/cache/img/svg/clipboard.svg
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>
|
||||||
|
After Width: | Height: | Size: 371 B |
1
static/cache/img/svg/external-link.svg
vendored
Normal file
1
static/cache/img/svg/external-link.svg
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>
|
||||||
|
After Width: | Height: | Size: 388 B |
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
@mixin violet-button-hover {
|
@mixin violet-button-hover {
|
||||||
background-color: $light-violet;
|
background-color: $light-violet;
|
||||||
cursor: grab;
|
cursor: pointer;
|
||||||
transform: translateY(-5px);
|
transform: translateY(-5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ $message-bg: #d63f3f;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.err__close:hover {
|
.err__close:hover {
|
||||||
cursor: grab;
|
cursor: pointer;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
33
templates/components/table/main.scss
Normal file
33
templates/components/table/main.scss
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import '../../vars';
|
||||||
|
|
||||||
|
@mixin table {
|
||||||
|
background-color: $white;
|
||||||
|
width: 90%;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin table__title-text {
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 0.75rem 0.5rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 0.1px solid $light-grey;
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
.button:hover {
|
.button:hover {
|
||||||
background-color: #993299;
|
background-color: #993299;
|
||||||
cursor: grab;
|
cursor: pointer;
|
||||||
transform: translateY(-5px);
|
transform: translateY(-5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import * as login from './auth/login/ts/';
|
|||||||
import * as register from './auth/register/ts/';
|
import * as register from './auth/register/ts/';
|
||||||
import * as panel from './panel/ts/index';
|
import * as panel from './panel/ts/index';
|
||||||
import * as addSiteKey from './panel/sitekey/add/ts';
|
import * as addSiteKey from './panel/sitekey/add/ts';
|
||||||
|
import * as listSitekeys from './panel/sitekey/list/ts';
|
||||||
import {MODE} from './logger';
|
import {MODE} from './logger';
|
||||||
import log from './logger';
|
import log from './logger';
|
||||||
|
|
||||||
@@ -48,6 +49,7 @@ const router = new Router();
|
|||||||
router.register(VIEWS.panelHome, panel.index);
|
router.register(VIEWS.panelHome, panel.index);
|
||||||
router.register(VIEWS.registerUser, register.index);
|
router.register(VIEWS.registerUser, register.index);
|
||||||
router.register(VIEWS.loginUser, login.index);
|
router.register(VIEWS.loginUser, login.index);
|
||||||
|
router.register(VIEWS.listSitekey, listSitekeys.index);
|
||||||
router.register(VIEWS.addSiteKey, addSiteKey.index);
|
router.register(VIEWS.addSiteKey, addSiteKey.index);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -23,3 +23,4 @@ import './panel/header/taskbar/mobile.scss';
|
|||||||
import './panel/navbar/mobile.scss';
|
import './panel/navbar/mobile.scss';
|
||||||
import './panel/help-banner/mobile.scss';
|
import './panel/help-banner/mobile.scss';
|
||||||
import './panel/sitekey/add/css/mobile.scss';
|
import './panel/sitekey/add/css/mobile.scss';
|
||||||
|
import './panel/sitekey/list/css/mobile.scss';
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="taskbar__action">
|
<li class="taskbar__action">
|
||||||
<img class="taskbar__icon" src="<.=
|
<img class="taskbar__icon" src="<.=
|
||||||
crate::FILES.get("./static/cache/img/svg/moon.svg").unwrap() .>" alt="Profile" />
|
crate::FILES.get("./static/cache/img/svg/moon.svg").unwrap() .>"
|
||||||
|
alt="Profile" />
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="taskbar__action">
|
<li class="taskbar__action">
|
||||||
@@ -26,7 +27,8 @@
|
|||||||
<li class="taskbar__action">
|
<li class="taskbar__action">
|
||||||
<a href="<.= crate::V1_API_ROUTES.auth.logout .>">
|
<a href="<.= crate::V1_API_ROUTES.auth.logout .>">
|
||||||
<img class="taskbar__icon" src="<.=
|
<img class="taskbar__icon" src="<.=
|
||||||
crate::FILES.get("./static/cache/img/svg/log-out.svg").unwrap() .>" alt="Profile"
|
crate::FILES.get("./static/cache/img/svg/log-out.svg").unwrap() .>"
|
||||||
/></a>
|
alt="Profile" /></a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -48,10 +48,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.taskbar__icon:hover {
|
.taskbar__icon:hover {
|
||||||
cursor: grab;
|
cursor: pointer;
|
||||||
background-color: $light-grey;
|
background-color: $light-grey;
|
||||||
color: $green;
|
color: $green;
|
||||||
background-color: $light-grey;
|
|
||||||
filter: invert(58%) sepia(60%) saturate(331%) hue-rotate(76deg)
|
filter: invert(58%) sepia(60%) saturate(331%) hue-rotate(76deg)
|
||||||
brightness(91%) contrast(92%);
|
brightness(91%) contrast(92%);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,63 @@
|
|||||||
<. include!("../components/headers/index.html"); .>
|
<. include!("../components/headers/index.html"); .> <.
|
||||||
<. include!("./navbar/index.html"); .>
|
include!("./navbar/index.html"); .>
|
||||||
<div class="tmp-layout">
|
<div class="tmp-layout">
|
||||||
<. include!("./header/index.html"); .>
|
<. include!("./header/index.html"); .>
|
||||||
<main class="panel-main">
|
<main class="panel-main">
|
||||||
<. include!("./help-banner/index.html"); .>
|
<. include!("./help-banner/index.html"); .>
|
||||||
<div class="inner-container">
|
<div class="inner-container">
|
||||||
|
|
||||||
<. if sitekeys.is_empty() { .>
|
<. if sitekeys.is_empty() { .>
|
||||||
<ul class="sitekey-list__box">
|
<ul class="sitekey-list__box">
|
||||||
<p>
|
<p>
|
||||||
It looks like you don't have any sitekeys. Click
|
It looks like you don't have any sitekeys. Click
|
||||||
<a href="<.= crate::PAGES.panel.sitekey.add .>">here</a> to add new sitekey.
|
<a href="<.= crate::PAGES.panel.sitekey.add .>">here</a> to add new
|
||||||
|
sitekey.
|
||||||
</p>
|
</p>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
<.} else {.>
|
<.} else {.>
|
||||||
<ul class="sitekey-list__box">
|
|
||||||
<h1 class="sitekey-list__title">Your Sitekeys</h1>
|
<table class="sitekey__table">
|
||||||
|
<thead class="sitekey__table-heading">
|
||||||
|
<tr>
|
||||||
|
<th colspan="4" class="sitekey__table-title-text">
|
||||||
|
Your Sitekeys
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="sitekey__body">
|
||||||
<. for sitekey in sitekeys.iter() { .>
|
<. for sitekey in sitekeys.iter() { .>
|
||||||
<a href="/sitekey/<.= sitekey.key .>/" class="sitekey-list__item-container">
|
<tr class="sitekey__item">
|
||||||
<li class="sitekey-list__item">
|
<td class="sitekey-list__name">
|
||||||
|
<a
|
||||||
<span class="sitekey-list__name">
|
href="/sitekey/<.= sitekey.key .>/"
|
||||||
|
class="sitekey-list__sitekey-link"
|
||||||
|
>
|
||||||
<.= sitekey.name .>
|
<.= sitekey.name .>
|
||||||
</span>
|
|
||||||
<span class="sitekey-list__key">
|
|
||||||
<.= sitekey.key .>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</a>
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="sitekey-list__key">
|
||||||
|
<div class="sitekey__key-container">
|
||||||
|
<img class="sitekey__copy-icon" src="<.= crate::FILES
|
||||||
|
.get("./static/cache/img/svg/clipboard.svg") .unwrap() .>"
|
||||||
|
alt="copy sitekey" data-sitekey="<.= sitekey.key .>" /> <img
|
||||||
|
class="sitekey__copy-done-icon" src="<.= crate::FILES
|
||||||
|
.get("./static/cache/img/svg/check.svg") .unwrap() .>"
|
||||||
|
alt="sitekey copied" data-sitekey="<.= sitekey.key .>" />
|
||||||
|
<a
|
||||||
|
class="sitekey__widget-link"
|
||||||
|
href="<.= crate::WIDGET_ROUTES.verification_widget .>/?sitekey=<.= sitekey.key .>"
|
||||||
|
>
|
||||||
|
<.= &sitekey.key[0..5] .>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<. } .>
|
<. } .>
|
||||||
</ul>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<.}.>
|
<.}.>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<. include!("../components/footers.html"); .>
|
<. include!("../components/footers.html"); .>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
}
|
}
|
||||||
.secondary-menu__heading:hover {
|
.secondary-menu__heading:hover {
|
||||||
color: $green;
|
color: $green;
|
||||||
cursor: grab;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary-menu__logo {
|
.secondary-menu__logo {
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
|
|
||||||
.secondary-menu__item-link:hover {
|
.secondary-menu__item-link:hover {
|
||||||
color: $green;
|
color: $green;
|
||||||
cursor: grab;
|
cursor: pointer;
|
||||||
filter: invert(58%) sepia(60%) saturate(331%) hue-rotate(76deg)
|
filter: invert(58%) sepia(60%) saturate(331%) hue-rotate(76deg)
|
||||||
brightness(91%) contrast(92%);
|
brightness(91%) contrast(92%);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav__hamburger-menu:hover {
|
.nav__hamburger-menu:hover {
|
||||||
cursor: grab;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav__hamburger-menu:hover > span {
|
.nav__hamburger-menu:hover > span {
|
||||||
@@ -75,5 +75,5 @@
|
|||||||
|
|
||||||
.secondary-menu__brand-name:hover {
|
.secondary-menu__brand-name:hover {
|
||||||
color: $light-text;
|
color: $light-text;
|
||||||
cursor: grab;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,20 +16,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@import '../../vars';
|
@import '../../vars';
|
||||||
|
@import '../../components//table/main';
|
||||||
|
|
||||||
.notification__table {
|
.notification__table {
|
||||||
background-color: $white;
|
@include table;
|
||||||
width: 90%;
|
margin: auto;
|
||||||
padding: 0 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification__title-text {
|
.notification__title-text {
|
||||||
font-size: 1rem;
|
@include table__title-text;
|
||||||
padding: 0.75rem 0.5rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
text-align: left;
|
|
||||||
width: 100%;
|
|
||||||
border-bottom: 0.1px solid $light-grey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification__mark-read-btn {
|
.notification__mark-read-btn {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ const submit = async (e: Event) => {
|
|||||||
const res = await fetch(formUrl, genJsonPayload(payload));
|
const res = await fetch(formUrl, genJsonPayload(payload));
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
window.location.assign(VIEWS.listSitekey(data.key));
|
window.location.assign(VIEWS.viewSitekey(data.key));
|
||||||
} else {
|
} else {
|
||||||
const err = await res.json();
|
const err = await res.json();
|
||||||
createError(err.error);
|
createError(err.error);
|
||||||
|
|||||||
@@ -18,38 +18,87 @@
|
|||||||
@import '../../../../reset';
|
@import '../../../../reset';
|
||||||
@import '../../../../vars';
|
@import '../../../../vars';
|
||||||
@import '../../../../components/box';
|
@import '../../../../components/box';
|
||||||
|
@import '../../../../components/table/main';
|
||||||
|
|
||||||
.sitekey-list__box {
|
.sitekey__table {
|
||||||
@include box;
|
@include table;
|
||||||
padding-bottom: 0px;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sitekey-list__title {
|
.sitekey__table-title-text {
|
||||||
@include box-title;
|
@include table__title-text;
|
||||||
}
|
|
||||||
|
|
||||||
.sitekey-list__item-container {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border-bottom: 0.1px solid $light-grey;
|
|
||||||
padding: 20px;
|
|
||||||
color: $black-text;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sitekey-list__item {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sitekey-list__item-container:hover {
|
|
||||||
background-color: $light-grey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sitekey-list__name {
|
.sitekey-list__name {
|
||||||
flex: 3;
|
min-width: 450px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sitekey-list__key {
|
.sitekey-list__key {
|
||||||
flex: 1;
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin copy-icon-base {
|
||||||
|
margin: auto;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey__copy-icon {
|
||||||
|
@include copy-icon-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey__copy-icon:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
filter: invert(17%) sepia(93%) saturate(5039%) hue-rotate(204deg)
|
||||||
|
brightness(100%) contrast(98%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey__copy-done-icon {
|
||||||
|
@include copy-icon-base;
|
||||||
|
display: none;
|
||||||
|
filter: invert(58%) sepia(60%) saturate(331%) hue-rotate(76deg)
|
||||||
|
brightness(91%) contrast(92%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey__key-container {
|
||||||
|
border-radius: 10px;
|
||||||
|
background: $backdrop;
|
||||||
|
margin: 2px;
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
max-width: 150px;
|
||||||
|
border: 0.1px solid rgba(0, 0, 0, 0.125);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey__widget-link {
|
||||||
|
border-left: 0.1px solid $light-grey;
|
||||||
|
margin: 5;
|
||||||
|
margin: auto;
|
||||||
|
padding-left: 20px;
|
||||||
|
height: 100%;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey-list__sitekey-link {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
text-decoration: none;
|
||||||
|
color: $blue-link;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey-list__sitekey-link:visited {
|
||||||
|
color: $blue-link;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey-list__sitekey-link:hover {
|
||||||
|
background-color: $light-grey;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey__widget-link {
|
||||||
|
color: $blue-link;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitekey__widget-link:visited {
|
||||||
|
color: $blue-link;
|
||||||
}
|
}
|
||||||
|
|||||||
20
templates/panel/sitekey/list/css/mobile.scss
Normal file
20
templates/panel/sitekey/list/css/mobile.scss
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sitekey-list__name {
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
@@ -1,23 +1,53 @@
|
|||||||
<. include!("../../../components/headers/index.html"); .>
|
<. include!("../../../components/headers/index.html"); .> <.
|
||||||
<. include!("../../navbar/index.html"); .>
|
include!("../../navbar/index.html"); .>
|
||||||
<div class="tmp-layout">
|
<div class="tmp-layout">
|
||||||
<. include!("../../header/index.html"); .>
|
<. include!("../../header/index.html"); .>
|
||||||
<main class="panel-main">
|
<main class="panel-main">
|
||||||
<.include!("../../help-banner/index.html"); .>
|
<.include!("../../help-banner/index.html"); .>
|
||||||
<!-- Main content container -->
|
<!-- Main content container -->
|
||||||
<div class="inner-container">
|
<div class="inner-container">
|
||||||
<!-- Main menu/ important actions roaster -->
|
<!-- Main menu/ important actions roaster -->
|
||||||
<ul class="sitekey-list__box">
|
<table class="sitekey__table">
|
||||||
<h1 class="sitekey-list__title">Your Sitekeys</h1>
|
<thead class="sitekey__table-heading">
|
||||||
|
<tr>
|
||||||
|
<th colspan="4" class="sitekey__table-title-text">
|
||||||
|
Your Sitekeys
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="sitekey__body">
|
||||||
<. for sitekey in sitekeys.iter() { .>
|
<. for sitekey in sitekeys.iter() { .>
|
||||||
<a href="/sitekey/<.= sitekey.key .>/" class="sitekey-list__item-container">
|
<tr class="sitekey__item">
|
||||||
<li class="sitekey-list__item">
|
<td class="sitekey-list__name">
|
||||||
<span class="sitekey-list__name"><.= sitekey.name .></span>
|
<a
|
||||||
<span class="sitekey-list__key"><.= sitekey.key .></span>
|
href="/sitekey/<.= sitekey.key .>/"
|
||||||
</li>
|
class="sitekey-list__sitekey-link"
|
||||||
|
>
|
||||||
|
<.= sitekey.name .>
|
||||||
</a>
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="sitekey-list__key">
|
||||||
|
<div class="sitekey__key-container">
|
||||||
|
<img class="sitekey__copy-icon" src="<.= crate::FILES
|
||||||
|
.get("./static/cache/img/svg/clipboard.svg") .unwrap() .>"
|
||||||
|
alt="copy sitekey" data-sitekey="<.= sitekey.key .>" /> <img
|
||||||
|
class="sitekey__copy-done-icon" src="<.= crate::FILES
|
||||||
|
.get("./static/cache/img/svg/check.svg") .unwrap() .>"
|
||||||
|
alt="sitekey copied" data-sitekey="<.= sitekey.key .>" />
|
||||||
|
<a
|
||||||
|
class="sitekey__widget-link"
|
||||||
|
href="<.= crate::WIDGET_ROUTES.verification_widget .>/?sitekey=<.= sitekey.key .>"
|
||||||
|
>
|
||||||
|
<.= &sitekey.key[0..5] .>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<. } .>
|
<. } .>
|
||||||
</ul>
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<!-- end of container -->
|
<!-- end of container -->
|
||||||
<. include!("../../../components/footers.html"); .>
|
<. include!("../../../components/footers.html"); .>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -15,4 +15,39 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const index = () => {};
|
export const index = () => {
|
||||||
|
registerCopySitekey();
|
||||||
|
};
|
||||||
|
|
||||||
|
const SITEKEY_COPY_ICON = `sitekey__copy-icon`;
|
||||||
|
const SITEKEY_COPY_DONE_ICON = `sitekey__copy-done-icon`;
|
||||||
|
|
||||||
|
const registerCopySitekey = () => {
|
||||||
|
const icons = document.querySelectorAll(`.${SITEKEY_COPY_ICON}`);
|
||||||
|
icons.forEach(icon => {
|
||||||
|
icon.addEventListener('click', e => copySitekey(e));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy sitekey to clipboard
|
||||||
|
*/
|
||||||
|
const copySitekey = async (e: Event) => {
|
||||||
|
const image = <HTMLElement>e.target;
|
||||||
|
if (!image.classList.contains(SITEKEY_COPY_ICON)) {
|
||||||
|
throw new Error(
|
||||||
|
'This method should only be called when sitekey copy button/icon is clicked',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const copyDoneIcon = <HTMLElement>(
|
||||||
|
image.parentElement.querySelector(`.${SITEKEY_COPY_DONE_ICON}`)
|
||||||
|
);
|
||||||
|
const sitekey = image.dataset.sitekey;
|
||||||
|
await navigator.clipboard.writeText(sitekey);
|
||||||
|
image.style.display = 'none';
|
||||||
|
copyDoneIcon.style.display = 'block';
|
||||||
|
setTimeout(() => {
|
||||||
|
copyDoneIcon.style.display = 'none';
|
||||||
|
image.style.display = 'block';
|
||||||
|
}, 1200);
|
||||||
|
};
|
||||||
|
|||||||
@@ -10,8 +10,15 @@
|
|||||||
<!-- Main menu/ important actions roaster -->
|
<!-- Main menu/ important actions roaster -->
|
||||||
<form class="sitekey-form" action="<.= crate::V1_API_ROUTES.levels.add .>" method="post">
|
<form class="sitekey-form" action="<.= crate::V1_API_ROUTES.levels.add .>" method="post">
|
||||||
<h1 class="form__title">Sitekey: <.= name .>
|
<h1 class="form__title">Sitekey: <.= name .>
|
||||||
<a href="<.= crate::WIDGET_ROUTES.verification_widget .>/?sitekey=<.= key.>"
|
<a
|
||||||
>Click here to see CAPTCHA widget in action</a>
|
target="_blank"
|
||||||
|
href="<.= crate::WIDGET_ROUTES.verification_widget .>/?sitekey=<.= key.>"
|
||||||
|
>View widget
|
||||||
|
<img class="sitekey-form__widget-link"
|
||||||
|
src="<.= crate::FILES.get("./static/cache/img/svg/external-link.svg").unwrap() .>"
|
||||||
|
alt="View widget deployment"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<label class="sitekey-form__label" for="description">
|
<label class="sitekey-form__label" for="description">
|
||||||
Description
|
Description
|
||||||
@@ -41,14 +48,11 @@
|
|||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|
||||||
<. for (count, level) in levels.iter().enumerate() { .>
|
<. for (count, level) in levels.iter().enumerate() { .>
|
||||||
<. include!("./existing-level.html"); .>
|
<. include!("./existing-level.html"); .>
|
||||||
<. } .>
|
<. } .>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- end of container -->
|
<!-- end of container -->
|
||||||
<. include!("../../../components/footers.html"); .>
|
<. include!("../../../components/footers.html"); .>
|
||||||
|
|||||||
@@ -15,72 +15,8 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import * as listSitekeys from '../sitekey/list/ts/';
|
||||||
|
|
||||||
export const index = () => {
|
export const index = () => {
|
||||||
// const html = document.documentElement;
|
listSitekeys.index();
|
||||||
// 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');
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// let a;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ const ROUTES = {
|
|||||||
signoutUser: '/api/v1/signout',
|
signoutUser: '/api/v1/signout',
|
||||||
panelHome: '/',
|
panelHome: '/',
|
||||||
docsHome: '/docs/',
|
docsHome: '/docs/',
|
||||||
listSitekey: (key: string) => `/sitekey/${key}/`,
|
listSitekey: '/sitekeys/',
|
||||||
addSiteKey: '/sitekey/add',
|
viewSitekey: (key: string) => `/sitekey/${key}/`,
|
||||||
|
addSiteKey: '/sitekeys/add',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ROUTES;
|
export default ROUTES;
|
||||||
|
|||||||
Reference in New Issue
Block a user