Several major changes: Added verification system, better loading screen, added documentation, optimizations, cleanups, etc, and finally fixed Markdown.

This commit is contained in:
Green! 2022-11-14 04:16:59 +00:00
parent bf0c2fb307
commit 38dde4ed38
16 changed files with 4311 additions and 4567 deletions

3
.breakpoints Normal file
View file

@ -0,0 +1,3 @@
{
"files": {}
}

View file

@ -2,50 +2,31 @@
<div align=center> <div align=center>
<img src='https://nebulaproxy.nebula.bio/images/logo.png' width="100px" height="100px"> <img src='https://nebulaproxy.nebula.bio/images/logo.png' width="100px" height="100px">
<h1> Nebula </h1> <h1> Nebula </h1>
Nebula Web is an official flagship of Nebula Services. Nebula Web is a stunning and sleak webproxy with support for hundreds of popular sites, and partial support for WebRTC, used in GfN. With Nebula Web, the sky is the limit. Enjoy. NebulaWeb is an official flagship of Nebula Services and Nebula Developer Labs. NebulaWeb is a stunning, sleak, and functional web-proxy with support for thousands of popular sites. With NebulaWeb, the sky is the limit.
</div> </div>
## Features ## Features
- Stunning UI with multiple themes - Stunning highly functional UI with multiple themes
- XOR/b64 Encrypts all traffic sent from Nebula - XOR/b64 Encrypts all traffic sent from Nebula
- Hides your IP from sites - Hides your IP from sites
- [List of officially supported sites](https://github.com/NebulaServices/Nebula/blob/main/docs/officially-supported-sites.md) - [List of officially supported sites](https://github.com/NebulaServices/Nebula/blob/main/docs/officially-supported-sites.md)
- *limited* mobile support - *limited* mobile support
- StealthMode (buffed `about:blank` cloaking) - StealthMode (buffed `about:blank` cloaking)
- Advanced cloaking options
- **NEW** Deployment option - Email OTP Verification (tutorial can be found below)
### Self Hosting
```bash
$ git clone https://github.com/NebulaServices/Nebula.git
$ cd Nebula
$ npm ci
$ npm start
```
## Tech Stack
- HTML, JS, CSS
- Partical.JS
- UV Backend Proxy
- Osana Backend Proxy
- **Server:** Bare server on Node
## Support
For support, email chloe@nebula.bio or join our discord: discord.nebula.bio
## Demo
[Click here to see a demo of Nebula](https://tutorialread.beauty/)
# Deployment # Deployment
## Quick Deployment Options Table of contents
- Quick & easy deployment
- how to use email OTP Verification mode
- Advanced Deployment
## Quick & Easy Deployment Options
[![Deploy to Heroku](https://raw.githubusercontent.com/BinBashBanana/deploy-buttons/master/buttons/remade/heroku.svg)](https://heroku.com/deploy/?template=https://github.com/NebulaServices/Nebula) [![Deploy to Heroku](https://raw.githubusercontent.com/BinBashBanana/deploy-buttons/master/buttons/remade/heroku.svg)](https://heroku.com/deploy/?template=https://github.com/NebulaServices/Nebula)
<br> <br>
[![Run on Replit](https://raw.githubusercontent.com/BinBashBanana/deploy-buttons/master/buttons/remade/replit.svg)](https://replit.com/github/NebulaServices/Nebula) [![Run on Replit](https://raw.githubusercontent.com/BinBashBanana/deploy-buttons/master/buttons/remade/replit.svg)](https://replit.com/github/NebulaServices/Nebula)
@ -63,6 +44,13 @@ For support, email chloe@nebula.bio or join our discord: discord.nebula.bio
[![Deploy To Koyeb](https://binbashbanana.github.io/deploy-buttons/buttons/remade/koyeb.svg)](https://app.koyeb.com/deploy?type=git&repository=github.com/NebulaServices/Nebula&branch=main&name=NebulaProxy) [![Deploy To Koyeb](https://binbashbanana.github.io/deploy-buttons/buttons/remade/koyeb.svg)](https://app.koyeb.com/deploy?type=git&repository=github.com/NebulaServices/Nebula&branch=main&name=NebulaProxy)
--- ---
## how to use email OTP Verification mode
* change `"verification":false,` to `"verification":true,`
* Make an account with Sendgrid (https://app.sendgrid.com/)
* verify email
* get API key
* fill out information in `deployment.config.json`
## Advanced Deployment ## Advanced Deployment
### Initial configuration ### Initial configuration
@ -112,6 +100,25 @@ sudo nohup PORT=80 node . &
*Note: Server will need to run` cd Nebula && sudo nohup PORT=80 node . &` on reboot* *Note: Server will need to run` cd Nebula && sudo nohup PORT=80 node . &` on reboot*
(Nebula's license is now GNU AGPL V3 as of v7.10) (Nebula's license is now GNU AGPL V3 as of v7.10)
## Tech Stack
- HTML, JS, CSS
- Partical.JS
- UV Backend Proxy
- Osana Backend Proxy
- **Server:** Bare server on Node
## Support
For support, email chloe@nebula.bio or join our discord: discord.nebula.bio
## Demo
[Click here to see a demo of Nebula](https://tutorialread.beauty/)
## Acknowledgements ## Acknowledgements
- [UV (one of the back-end proxy we use)](https://github.com/titaniumnetwork-dev/Ultraviolet) - [UV (one of the back-end proxy we use)](https://github.com/titaniumnetwork-dev/Ultraviolet)

154
app.js
View file

@ -1,54 +1,142 @@
import createBareServer from '@tomphttp/bare-server-node'; import createBareServer from "@tomphttp/bare-server-node"
import http from 'http'; import http from "http"
import { fileURLToPath } from 'url'; import { fileURLToPath } from "url"
import { dirname, join } from 'path'; import { dirname, join } from "path"
import serveStatic from 'serve-static'; import serveStatic from "serve-static"
import { createRequire } from "module"
const require = createRequire(import.meta.url)
const config = require("./deployment.config.json")
import fs from "fs"
var base64data
import sgTransport from "nodemailer-sendgrid-transport"
import nodemailer from "nodemailer"
const options = {
auth: {
api_key: config.api_key,
},
}
const mailerAgent = nodemailer.createTransport(sgTransport(options))
function sendVerificationEmail(UUID, mailTo, OTP) {
const email = {
to: mailTo,
from: `${config.sendFromEmail}`,
subject: `NebulaWEB personal access code ${OTP}`,
text: `
####### ACCESS CODE (OTP) ${OTP} #######
####### DO NOT SHARE THIS CODE! #######
(this message is automated)`,
html: `
####### ACCESS CODE (OTP) ${OTP} #######
####### DO NOT SHARE THIS CODE! #######
(this message is automated)
`,
}
if (config.verification == true) {
mailerAgent.sendMail(email, (err, res) => {
if (err) {
console.log(err)
}
console.log(res)
})
}
}
const PORT = process.env.PORT || 3000; function getNewCode() {
const bareServer = createBareServer('/bare/', { var seq = (Math.floor(Math.random() * 10000) + 10000).toString().substring(1)
if (seq == "0") {
getNewCode()
}
return seq
}
const PORT = process.env.PORT || 3000
const bareServer = createBareServer("/bare/", {
logErrors: false, logErrors: false,
localAddress: undefined localAddress: undefined,
}); })
const serve = serveStatic(join( const serve = serveStatic(
dirname(fileURLToPath(import.meta.url)), join(dirname(fileURLToPath(import.meta.url)), "static/"),
'static/' {
), { fallthrough: false,
fallthrough: false, maxAge: 5 * 60 * 1000,
maxAge: 5 * 60 * 1000 }
}); )
const server = http.createServer(); const server = http.createServer()
server.on('request', (request, response) => { server.on("request", (request, response) => {
try { try {
if (bareServer.shouldRoute(request)) { if (bareServer.shouldRoute(request)) {
bareServer.routeRequest(request, response); bareServer.routeRequest(request, response)
} else { } else {
serve(request, response, err => { let base64data
response.writeHead(err?.statusCode || 500, null, { const url = request.url
"Content-Type": "text/plain" if (url.startsWith("/sendNewCode")) {
const OTP = getNewCode()
fs.writeFile("./memory.txt", OTP, function (err) {
if (err) return console.log(err)
console.log(`Wrote OTP code to temp file`)
}) })
response.end(err?.stack)
}); fs.readFile("./memory.txt", "utf8", (err, data) => {
if (err) {
console.error(err)
return
}
console.log(data)
sendVerificationEmail("10", config.email, data)
let buff = new Buffer(data)
base64data = buff.toString("base64")
console.log("302")
response.writeHead(302, {
location: "/unv.html?c=" + base64data,
})
response.end()
})
} else if (url.startsWith("/verification")) {
var body
if (config.verification == true) {
const body = "true"
response.writeHead(200, {
"Content-Length": Buffer.byteLength(body),
"Content-Type": "text/plain",
})
response.end(body)
} else {
const body = "false"
response.writeHead(200, {
"Content-Length": Buffer.byteLength(body),
"Content-Type": "text/plain",
})
response.end(body)
}
} else {
serve(request, response, (err) => {
response.writeHead(err?.statusCode || 500, null, {
"Content-Type": "text/plain",
})
response.end(err?.stack)
})
}
} }
} catch (e) { } catch (e) {
response.writeHead(500, "Internal Server Error", { response.writeHead(500, "Internal Server Error", {
"Content-Type": "text/plain" "Content-Type": "text/plain",
}) })
response.end(e.stack) response.end(e.stack)
} }
}); })
server.on('upgrade', (req, socket, head) => { server.on("upgrade", (req, socket, head) => {
if (bareServer.shouldRoute(req)) { if (bareServer.shouldRoute(req)) {
bareServer.routeUpgrade(req, socket, head); bareServer.routeUpgrade(req, socket, head)
} else { } else {
socket.end(); socket.end()
} }
}); })
server.listen(PORT); server.listen(PORT)
if (process.env.UNSAFE_CONTINUE) if (process.env.UNSAFE_CONTINUE)
process.on("uncaughtException", (err, origin) => { process.on("uncaughtException", (err, origin) => {
@ -58,4 +146,4 @@ if (process.env.UNSAFE_CONTINUE)
console.error() console.error()
}) })
console.log(`Server running at http://localhost:${PORT}/.`); console.log(`Server running at http://localhost:${PORT}/.`)

7
deployment.config.json Normal file
View file

@ -0,0 +1,7 @@
{
"verification": false,
"api_key":"YOUR_SENDGRID_API_KEY",
"sendFromEmail":"THE EMAIL THE CODES WILL BE SENT FROM (MUST BE VERIFIED IN SENDGRID)",
"type": "code",
"email": "YOUR_EMAIL_HERE"
}

1
memory.txt Normal file
View file

@ -0,0 +1 @@
5003

2472
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,8 @@
"crypto-js": "4.1.1", "crypto-js": "4.1.1",
"css-tree": "^2.1.0", "css-tree": "^2.1.0",
"node-fetch": "^3.2.6", "node-fetch": "^3.2.6",
"nodemailer": "^6.8.0",
"nodemailer-sendgrid-transport": "^0.2.0",
"serve-static": "^1.15.0", "serve-static": "^1.15.0",
"ws": "^8.8.1" "ws": "^8.8.1"
}, },

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

12
static/resources/v.js Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,168 +1,174 @@
@import url("https://fonts.googleapis.com/css2?family=Dongle&family=Roboto:wght@100&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Dongle&family=Roboto:wght@100&display=swap");
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@1,100&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@1,100&display=swap');
:root { :root {
--background-primary: #191724; --background-primary: #191724;
--navbar-color: #26233a; --navbar-color: #26233a;
--navbar-height: 60px; --navbar-height: 60px;
--navbar-text-color: #7967dd; --navbar-text-color: #7967dd;
--navbar-link-color: #e0def4; --navbar-link-color: #e0def4;
--navbar-font: "Roboto"; --navbar-font: "Roboto";
--input-text-color: #e0def4; --input-text-color: #e0def4;
--input-placeholder-color: white; --input-placeholder-color: white;
--input-background-color: #1f1d2e; --input-background-color: #1f1d2e;
--input-border-color: #eb6f92; --input-border-color: #eb6f92;
--input-border-size: 1.3px; --input-border-size: 1.3px;
--navbar-logo-filter: none; --navbar-logo-filter: none;
} }
::-webkit-input-placeholder { ::-webkit-input-placeholder {
text-align: center; text-align: center;
font-family: 'Roboto'; font-family: 'Roboto';
} }
:-moz-placeholder { :-moz-placeholder {
text-align: center; text-align: center;
} }
#navbar { #navbar {
height: var(--navbar-height); height: var(--navbar-height);
text-align: center; text-align: center;
align-items: center; align-items: center;
display: flex; display: flex;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
background-color: var(--navbar-color); background-color: var(--navbar-color);
} }
.sidenav-btn { .sidenav-btn {
display: none; display: none;
} }
.sidenav { .sidenav {
height: 100%; height: 100%;
width: 0; width: 0;
position: fixed; position: fixed;
z-index: 1; z-index: 1;
top: 0; top: 0;
left: 0; left: 0;
background-color: #232133; background-color: #232133;
padding-top: 60px; padding-top: 60px;
-webkit-transition: 0.5s; -webkit-transition: 0.5s;
transition: 0.5s; transition: 0.5s;
overflow: hidden; overflow: hidden;
} }
.sidenav a { .sidenav a {
padding: 8px 16px 16px 32px; padding: 8px 16px 16px 32px;
text-decoration: none; text-decoration: none;
width: 100vw; width: 100vw;
font-size: 24px; font-size: 24px;
color: #cfcfcf; color: #cfcfcf;
display: block; display: block;
transition: 0.3s; transition: 0.3s;
} }
.sidenav .closebtn { .sidenav .closebtn {
position: absolute; position: absolute;
top: 0; top: 0;
right: 25px; right: 25px;
font-size: 36px; font-size: 36px;
margin-left: 50px; margin-left: 50px;
z-index: 2; z-index: 2;
left: 140px; left: 140px;
} }
@media only screen and (max-width: 690px) { /* funny number */ @media only screen and (max-width: 690px) {
/* funny number */
#navbar > ul > li { #navbar>ul>li {
display: none; display: none;
} }
.sidenav-btn { .sidenav-btn {
display: flex; display: flex;
align-items: center; align-items: center;
position: absolute; position: absolute;
left: 90vw; left: 90vw;
width: var(--navbar-height); width: var(--navbar-height);
height: var(--navbar-height); height: var(--navbar-height);
} }
.sidenav-btn > svg {
width: 50px;
height: 50px;
}
#digitalCLOContainerLI { .sidenav-btn>svg {
display: none; width: 50px;
} height: 50px;
#navbar > ul > li > a > svg { }
min-width: 24px;
} #digitalCLOContainerLI {
display: none;
}
#navbar>ul>li>a>svg {
min-width: 24px;
}
} }
a { a {
color: var(--navbar-link-color); color: var(--navbar-link-color);
text-decoration: none !important; text-decoration: none !important;
font-family: 'Roboto'; font-family: 'Roboto';
} }
a:hover { a:hover {
color: grey; color: grey;
transition: 0.5s; transition: 0.5s;
cursor: pointer; cursor: pointer;
} }
.down { .down {
background-color: rgb(90, 24, 154); background-color: rgb(90, 24, 154);
left: inherit !important; left: inherit !important;
font-family: 'Helvetica'; font-family: 'Helvetica';
background-color: var(--navbar-color); background-color: var(--navbar-color);
/* box-shadow: 2px 2px rgb(0 0 0 / 20%); */ /* box-shadow: 2px 2px rgb(0 0 0 / 20%); */
color: white; color: white;
display: none; display: none;
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
list-style-type: none; list-style-type: none;
position: fixed; position: fixed;
border-bottom-right-radius: 10px; border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
list-style-type: none; list-style-type: none;
} }
#navbar ul:not(.down) { #navbar ul:not(.down) {
font-family: 'Helvetica'; font-family: 'Helvetica';
/* box-shadow: 2px 2px rgb(0 0 0 / 20%); */ /* box-shadow: 2px 2px rgb(0 0 0 / 20%); */
color: white; color: white;
margin-left: auto; margin-left: auto;
list-style-type: none; list-style-type: none;
float: right !important; float: right !important;
margin-right: 2.3%; margin-right: 2.3%;
display: flex; display: flex;
align-items: center; align-items: center;
} }
#navbar ul li { #navbar ul li {
float: left; float: left;
padding-top: 1em; padding-top: 1em;
padding-bottom: 1em; padding-bottom: 1em;
padding-right: 1em; padding-right: 1em;
padding-left: 1em; padding-left: 1em;
padding: 1rem; padding: 1rem;
} }
::placeholder, ::placeholder,
input[type='text'] { input[type='text'] {
color: var(--input-placeholder-color); color: var(--input-placeholder-color);
font-size: 20px; font-size: 20px;
text-align: center; text-align: center;
font-family: 'Roboto'; font-family: 'Roboto';
} }
#navbar ul p, #navbar ul p,
ul a { ul a {
font-weight: bold; font-weight: bold;
display: flex; display: flex;
align-items: center; align-items: center;
} }
*/ */
@ -173,316 +179,328 @@ ul a {
*/ */
#navbar ul li ul { #navbar ul li ul {
border-bottom-right-radius: 10px; border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
margin-top: 1rem; margin-top: 1rem;
left: 0; left: 0;
display: none; display: none;
} }
#navbar ul li:hover ul, #navbar ul li:hover ul,
ul li ul:hover { ul li ul:hover {
visibility: visible; visibility: visible;
opacity: 1; opacity: 1;
display: block; display: block;
} }
#navbar ul li p { #navbar ul li p {
color: white; color: white;
font-family: 'Calibri'; font-family: 'Calibri';
z-index: 3 !important; z-index: 3 !important;
} }
#navbar ul li ul li { #navbar ul li ul li {
clear: both; clear: both;
width: 100%; width: 100%;
} }
#content { #content {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 98%; height: 98%;
color: white; color: white;
flex-direction: column; flex-direction: column;
font-family: 'Roboto'; font-family: 'Roboto';
} }
#content h1 { #content h1 {
padding-bottom: 0.5em; padding-bottom: 0.5em;
font-weight: 100; font-weight: 100;
text-align: center; text-align: center;
} }
#content img { #content img {
padding-left: .5em; padding-left: .5em;
filter: brightness(0) invert(1); filter: brightness(0) invert(1);
} }
#content input { #content input {
font-size: 20px; font-size: 20px;
text-align: center; text-align: center;
font-family: 'Calibri'; font-family: 'Calibri';
border-style: solid !important; border-style: solid !important;
border: var(--input-border-size) solid var(--input-border-color); border: var(--input-border-size) solid var(--input-border-color);
border-width: 1px; border-width: 1px;
border-radius: 15px; border-radius: 15px;
background-color: var(--input-background-color); background-color: var(--input-background-color);
color: var(--input-text-color); color: var(--input-text-color);
width: 300px; width: 300px;
height: 50px; height: 50px;
box-shadow: none !important; box-shadow: none !important;
outline: none; outline: none;
text-align: center; text-align: center;
font-family: 'Roboto'; font-family: 'Roboto';
} }
#content input:focus { #content input:focus {
outline: none; outline: none;
box-shadow: none !important; box-shadow: none !important;
} }
@keyframes inputwide { @keyframes inputwide {
0% { 0% {
width: 0px; width: 0px;
transition-duration: 0.5s; transition-duration: 0.5s;
} }
100% {
width: 300px; 100% {
transition-duration: 0.5s; width: 300px;
} transition-duration: 0.5s;
}
} }
.loader { .loader {
width: 283px; width: 283px;
text-align: center; text-align: center;
display: none; display: none;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-direction: row; flex-direction: row;
transition: .1s; transition: .1s;
} }
svg path, svg path,
svg rect { svg rect {
fill: #eb6f92; fill: #eb6f92;
} }
.connector { .connector {
color: white; color: white;
margin-left: 10px; margin-left: 10px;
font-size: 15px; font-size: 15px;
} }
@keyframes popout { @keyframes popout {
0% { 0% {
height: -20px; height: -20px;
} }
100% {
height: 0px; 100% {
} height: 0px;
}
} }
.nebHeader { .nebHeader {
font-family: var(--navbar-font); font-family: var(--navbar-font);
color: var(--navbar-text-color); color: var(--navbar-text-color);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
align-content: center; align-content: center;
flex-wrap: nowrap; flex-wrap: nowrap;
flex-direction: row; flex-direction: row;
margin-left: .5%; margin-left: .5%;
} }
html, html,
body { body {
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 100%; height: 100%;
} }
body { body {
background-color: var(--background-primary); background-color: var(--background-primary);
color: var(--text-color-primary); color: var(--text-color-primary);
animation: fadeInAnimation ease 1s; animation: fadeInAnimation ease 1s;
animation-iteration-count: 1; animation-iteration-count: 1;
animation-fill-mode: forwards; animation-fill-mode: forwards;
} }
@keyframes fadeInAnimation { @keyframes fadeInAnimation {
0% { 0% {
opacity: 0; opacity: 0;
} }
100% {
opacity: 1; 100% {
} opacity: 1;
}
} }
input:focus::placeholder { input:focus::placeholder {
color: transparent; color: transparent;
} }
#navbar #thumbImg { #navbar #thumbImg {
transition: width 2s, height 2s, transform 2s; transition: width 2s, height 2s, transform 2s;
filter: var(--navbar-logo-filter); filter: var(--navbar-logo-filter);
} }
#navbar #thumbImg:hover { #navbar #thumbImg:hover {
transform: rotate(360deg); transform: rotate(360deg);
} }
.stamp { .stamp {
text-align: right; text-align: right;
position: fixed; position: fixed;
bottom: 0; bottom: 0;
font-family: 'Montserrat', sans-serif; font-family: 'Montserrat', sans-serif;
font-style: italic; font-style: italic;
font-weight: lighter; font-weight: lighter;
color: whitesmoke; color: whitesmoke;
opacity: 90%; opacity: 90%;
user-select: none; user-select: none;
font-size: 13px; font-size: 13px;
padding-left: 5px; padding-left: 5px;
padding-bottom: 1px; padding-bottom: 1px;
cursor: default; cursor: default;
} }
.stamp:hover { .stamp:hover {
text-align: right; text-align: right;
position: fixed; position: fixed;
bottom: 0; bottom: 0;
font-family: 'Montserrat', sans-serif; font-family: 'Montserrat', sans-serif;
font-style: italic; font-style: italic;
font-weight: lighter; font-weight: lighter;
color: whitesmoke; color: whitesmoke;
opacity: 38%; opacity: 38%;
user-select: none; user-select: none;
font-size: 13px; font-size: 13px;
padding-left: 5px; padding-left: 5px;
padding-bottom: 1px; padding-bottom: 1px;
cursor: default; cursor: default;
} }
.github { .github {
position: fixed; position: fixed;
right: 0; right: 0;
bottom: 0; bottom: 0;
padding-right: 10px; padding-right: 10px;
} }
.tos { .tos {
position: fixed; position: fixed;
right: 67px; right: 67px;
bottom: 0; bottom: 0;
padding-right: 15px; padding-right: 15px;
} }
.privacy { .privacy {
position: fixed; position: fixed;
right: 114px; right: 114px;
bottom: 0; bottom: 0;
padding-right: 15px; padding-right: 15px;
} }
.modal-window { .modal-window {
position: fixed; position: fixed;
background-color: rgba(255, 255, 255, 0.25); background-color: rgba(255, 255, 255, 0.25);
top: 0; top: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
z-index: 999; z-index: 999;
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
pointer-events: none; pointer-events: none;
transition: all 0.3s; transition: all 0.3s;
font-family: 'Montserrat', sans-serif;; font-family: 'Montserrat', sans-serif;
;
} }
.modal-window:target { .modal-window:target {
visibility: visible; visibility: visible;
opacity: 1; opacity: 1;
pointer-events: auto; pointer-events: auto;
} }
.modal-window > div {
width: 400px; .modal-window>div {
position: absolute; width: 400px;
top: 50%; position: absolute;
left: 50%; top: 50%;
transform: translate(-50%, -50%); left: 50%;
padding: 2em; transform: translate(-50%, -50%);
background: white; padding: 2em;
background: white;
} }
.modal-window header { .modal-window header {
font-weight: bold; font-weight: bold;
} }
.modal-window h1 { .modal-window h1 {
font-size: 150%; font-size: 150%;
margin: 0 0 15px; margin: 0 0 15px;
} }
.modal-close { .modal-close {
color: #aaa; color: #aaa;
line-height: 50px; line-height: 50px;
font-size: 80%; font-size: 80%;
position: absolute; position: absolute;
right: 0; right: 0;
text-align: center; text-align: center;
top: 0; top: 0;
width: 70px; width: 70px;
text-decoration: none; text-decoration: none;
} }
.modal-close:hover { .modal-close:hover {
color: black; color: black;
} }
.modal-window>div {
.modal-window > div { border-radius: 1rem;
border-radius: 1rem;
} }
.modal-window div:not(:last-of-type) { .modal-window div:not(:last-of-type) {
margin-bottom: 15px; margin-bottom: 15px;
} }
.logo { .logo {
max-width: 150px; max-width: 150px;
display: block; display: block;
} }
small { small {
color: lightgray; color: lightgray;
} }
.btn { .btn {
background-color: white; background-color: white;
padding: 1em 1.5em; padding: 1em 1.5em;
border-radius: 0.5rem; border-radius: 0.5rem;
text-decoration: none; text-decoration: none;
} }
.btn i { .btn i {
padding-right: 0.3em; padding-right: 0.3em;
} }
@media only screen and (max-width: 1100px) { @media only screen and (max-width: 1100px) {
#digitalClock { #digitalClock {
display: none; display: none;
} }
} }
.clockColon { .clockColon {
opacity: 100%; opacity: 100%;
animation: blink .5s step-end infinite alternate; animation: blink .5s step-end infinite alternate;
transition: 0.2s; transition: 0.2s;
} }
@keyframes blink { @keyframes blink {
50% { 50% {
opacity: 0% opacity: 0%
} }
} }

View file

@ -1,24 +1,25 @@
@import url("https://fonts.googleapis.com/css2?family=Work+Sans:wght@300&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Work+Sans:wght@300&display=swap");
:root { :root {
--background-primary: #191724; --background-primary: #191724;
--sidebar-color: #191724; --sidebar-color: #191724;
--sidebar-text-color: #e0def4; --sidebar-text-color: #e0def4;
--text-color-primary: #e0def4; --text-color-primary: #e0def4;
--text-color-secondary: #6e6a86; --text-color-secondary: #6e6a86;
--focus-color: #eb6f92; --focus-color: #eb6f92;
--header-height: 10vh; --header-height: 10vh;
--section-font-size: 20pt; --section-font-size: 20pt;
--section-font: 'Calibri'; --section-font: 'Calibri';
--section-padding: 0.5em; --section-padding: 0.5em;
--setting-distance-from-sidebar: 1em; --setting-distance-from-sidebar: 1em;
--setting-distance-from-right: 1em; --setting-distance-from-right: 1em;
--setting-name-font: 'Calibri'; --setting-name-font: 'Calibri';
--setting-desc-font: 'Calibri'; --setting-desc-font: 'Calibri';
} }
* { * {
user-select: none; user-select: none;
} }
@ -28,47 +29,47 @@ body {
}*/ }*/
.container { .container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-content: center; align-content: center;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-evenly; justify-content: space-evenly;
align-items: flex-end; align-items: flex-end;
margin-top: 75px; margin-top: 75px;
} }
#sidebar { #sidebar {
animation: fadeIn 700ms ease-in 30ms forwards; animation: fadeIn 700ms ease-in 30ms forwards;
-webkit-animation: fadeIn 700ms ease-in 300ms forwards; -webkit-animation: fadeIn 700ms ease-in 300ms forwards;
position: absolute; position: absolute;
top: var(--header-height); top: var(--header-height);
left: 0; left: 0;
background-color: var(--sidebar-color); background-color: var(--sidebar-color);
transition: width 0.5s; transition: width 0.5s;
width: var(--sidebar-width); width: var(--sidebar-width);
} }
.setting li a { .setting li a {
background-color: #2e2828; background-color: #2e2828;
padding: 10px 16px; padding: 10px 16px;
border-radius: 5px; border-radius: 5px;
} }
.settings-div li a ul { .settings-div li a ul {
border-bottom-right-radius: 10px; border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
margin-top: 10px; margin-top: 10px;
left: 0 !important; left: 0 !important;
display: none; display: none;
} }
.settings-div li a:hover ul, .settings-div li a:hover ul,
ul li:hover { ul li:hover {
visibility: visible; visibility: visible;
opacity: 1; opacity: 1;
display: block; display: block;
} }
@ -81,406 +82,414 @@ ul li:hover {
}*/ }*/
li { li {
list-style-type: none; list-style-type: none;
} }
.settings-div li a ul li { .settings-div li a ul li {
clear: both; clear: both;
width: 100%; width: 100%;
} }
.section { .section {
background-color: transparent; background-color: transparent;
color: var(--sidebar-text-color); color: var(--sidebar-text-color);
font-size: var(--section-font-size); font-size: var(--section-font-size);
font-family: var(--section-font); font-family: var(--section-font);
width: 100%; width: 100%;
transition: background-color 0.5s; transition: background-color 0.5s;
padding-top: var(--section-padding); padding-top: var(--section-padding);
padding-bottom: var(--section-padding); padding-bottom: var(--section-padding);
} }
.section:hover { .section:hover {
background-color: #ffffff20; background-color: #ffffff20;
} }
.settings-div { .settings-div {
position: absolute; position: absolute;
left: calc(var(--sidebar-width) + var(--setting-distance-from-sidebar)); left: calc(var(--sidebar-width) + var(--setting-distance-from-sidebar));
top: 0; top: 0;
width: calc(100vw - var(--sidebar-width) - var(--setting-distance-from-sidebar)); width: calc(100vw - var(--sidebar-width) - var(--setting-distance-from-sidebar));
padding-top: 5%; padding-top: 5%;
} }
.setting-input { .setting-input {
/* left: 100%; */ /* left: 100%; */
color: black !important; color: black !important;
position: relative; position: relative;
/* right: 0; */ /* right: 0; */
transform: translateY(-1.5em); transform: translateY(-1.5em);
float: right; float: right;
margin-right: 5%; margin-right: 5%;
} }
.setting-input { .setting-input {
display: none; display: none;
} }
@import url('https://fonts.googleapis.com/css2?family=Mulish:wght@300&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@300&display=swap');
.toogle-button { .toogle-button {
font-weight: bold; font-weight: bold;
font-size: 10PX; font-size: 10PX;
display: inline-block; display: inline-block;
width: 75px; width: 75px;
height: 35px; height: 35px;
background-color: #dfddf3; background-color: #dfddf3;
border-radius: 30px; border-radius: 30px;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
} }
.toogle-button::after { .toogle-button::after {
content: 'Off'; content: 'Off';
width: 40px; width: 40px;
height: 40px; height: 40px;
color: #E7E2CD; color: #E7E2CD;
background-color: #e14343; background-color: #e14343;
border: 2px solid #E7E2CD; border: 2px solid #E7E2CD;
border-radius: 50%; border-radius: 50%;
box-shadow: 0 0 5px rgb(0 0 0 / 25%); box-shadow: 0 0 5px rgb(0 0 0 / 25%);
position: absolute; position: absolute;
top: -3px; top: -3px;
left: 0; left: 0;
line-height: 0; line-height: 0;
display: grid; display: grid;
place-content: center; place-content: center;
transition: all .5s; transition: all .5s;
transform: 1s ease-in; transform: 1s ease-in;
font-family: 'Mulish', sans-serif; font-family: 'Mulish', sans-serif;
} }
.setting-input:checked+.toogle-button::after { .setting-input:checked+.toogle-button::after {
content: 'On'; content: 'On';
background-color: #53b357; background-color: #53b357;
transform: translateX(35px) rotate(360deg); transform: translateX(35px) rotate(360deg);
} }
ul li { ul li {
float: left; float: left;
padding-top: 1em; padding-top: 1em;
padding-bottom: 1em; padding-bottom: 1em;
padding-right: 1em; padding-right: 1em;
padding-left: 1em; padding-left: 1em;
padding: 1rem; padding: 1rem;
} }
.button { .button {
width: 30px; width: 30px;
height: 30px; height: 30px;
transform: translateY(-30px); transform: translateY(-30px);
font-family: var(--setting-desc-font); font-family: var(--setting-desc-font);
color: white; color: white;
} }
@-webkit-keyframes fadeIn { @-webkit-keyframes fadeIn {
0% { 0% {
opacity: 0.01; opacity: 0.01;
} }
100% {
opacity: 1; 100% {
} opacity: 1;
}
} }
@keyframes fadeIn { @keyframes fadeIn {
0% { 0% {
opacity: 0.01; opacity: 0.01;
} }
100% {
opacity: 1; 100% {
} opacity: 1;
}
} }
@import url('https://fonts.googleapis.com/css?family=Roboto:400,500&display=swap'); @import url('https://fonts.googleapis.com/css?family=Roboto:400,500&display=swap');
.notification-container { .notification-container {
position: fixed; position: fixed;
top: 4px; top: 4px;
right: 5px; right: 5px;
width: 500px; width: 500px;
max-width: calc(100% - 30px); max-width: calc(100% - 30px);
font-family: 'Roboto', sans-serif; font-family: 'Roboto', sans-serif;
} }
.notification { .notification {
background-color: #fff; background-color: #fff;
border-radius: 5px; border-radius: 5px;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
color: #fff; color: #fff;
font-size: 16px; font-size: 16px;
padding: 15px 20px; padding: 15px 20px;
line-height: 20px; line-height: 20px;
margin-bottom: 15px; margin-bottom: 15px;
animation: grow 0.5s ease-in forwards; animation: grow 0.5s ease-in forwards;
} }
@keyframes grow { @keyframes grow {
from { from {
opacity: 0; opacity: 0;
transform: scale(0.8); transform: scale(0.8);
} }
to {
opacity: 1; to {
transform: scale(1); opacity: 1;
} transform: scale(1);
}
} }
.notification.hide { .notification.hide {
animation: shrink 0.3s ease-out forwards; animation: shrink 0.3s ease-out forwards;
} }
@keyframes shrink { @keyframes shrink {
to { to {
opacity: 0; opacity: 0;
transform: scale(0.8); transform: scale(0.8);
} }
} }
.notification strong { .notification strong {
font-size: 12px; font-size: 12px;
line-height: 20px; line-height: 20px;
letter-spacing: 0.5px; letter-spacing: 0.5px;
text-transform: uppercase; text-transform: uppercase;
} }
.notification-info { .notification-info {
background-color: #00cae3; background-color: #00cae3;
} }
.notification-success { .notification-success {
background-color: #3d3571; background-color: #3d3571;
} }
.notification-warning { .notification-warning {
background-color: #ff9e0f; background-color: #ff9e0f;
} }
.notification-danger { .notification-danger {
background-color: #f55145; background-color: #f55145;
} }
.stamp { .stamp {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
} }
.bk-btn { .bk-btn {
height: 52px; height: 52px;
width: 52px; width: 52px;
background-color: black; background-color: black;
border-radius: 50%; border-radius: 50%;
} }
.bk-btn .bk-btn-triangle { .bk-btn .bk-btn-triangle {
position: relative; position: relative;
top: 13px; top: 13px;
left: 10.4px; left: 10.4px;
width: 0; width: 0;
height: 0; height: 0;
border-top: 13px solid transparent; border-top: 13px solid transparent;
border-bottom: 13px solid transparent; border-bottom: 13px solid transparent;
border-right: 13px solid white; border-right: 13px solid white;
} }
.bk-btn .bk-btn-bar { .bk-btn .bk-btn-bar {
position: relative; position: relative;
background-color: white; background-color: white;
height: 7.8px; height: 7.8px;
width: 13px; width: 13px;
top: -3.64px; top: -3.64px;
left: 22.88px; left: 22.88px;
} }
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300&display=swap');
.settings-cont { .settings-cont {
background: #45454521; background: #45454521;
box-sizing: border-box; box-sizing: border-box;
width: 300px; width: 300px;
height: 246px; height: 246px;
padding: 30px; padding: 30px;
border: 2px solid rgb(0 0 0 / 64%); border: 2px solid rgb(0 0 0 / 64%);
border-radius: 9px; border-radius: 9px;
margin-top: 20px; margin-top: 20px;
display: flex; display: flex;
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
} }
.name { .name {
color: var(--text-color-primary); color: var(--text-color-primary);
font-size: 27px; font-size: 27px;
margin: 0; margin: 0;
font-family: 'Ubuntu', sans-serif; font-family: 'Ubuntu', sans-serif;
font-weight: 700; font-weight: 700;
font-style: bold; font-style: bold;
} }
.description { .description {
color: var(--text-color-secondary); color: var(--text-color-secondary);
margin: 0; margin: 0;
font-size: 17px; font-size: 17px;
font-family: 'Ubuntu', sans-serif; font-family: 'Ubuntu', sans-serif;
font-weight: 300; font-weight: 300;
/* font-style: Italic; */ /* font-style: Italic; */
text-align: center; text-align: center;
} }
@import url('https://fonts.googleapis.com/css2?family=Oxygen:wght@700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Oxygen:wght@700&display=swap');
.new-tag { .new-tag {
font-size: 16px; font-size: 16px;
color: rgb(226, 68, 68); color: rgb(226, 68, 68);
font-family: 'Oxygen', sans-serif; font-family: 'Oxygen', sans-serif;
} }
.square { .square {
width: .7em; width: .7em;
height: .7em; height: .7em;
margin: .5em; margin: .5em;
} }
/* Custom dropdown */ /* Custom dropdown */
.custom-dropdown { .custom-dropdown {
position: relative; position: relative;
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
margin: 10px; margin: 10px;
/* demo only */ /* demo only */
} }
.custom-dropdown select { .custom-dropdown select {
background-color: rgb(121 103 221); background-color: rgb(121 103 221);
color: var(--text-color-primary); color: var(--text-color-primary);
font-size: inherit; font-size: inherit;
padding: .5em; padding: .5em;
padding-right: 2.5em; padding-right: 2.5em;
border: 0; border: 0;
margin: 0; margin: 0;
border-radius: 3px; border-radius: 3px;
text-indent: 0.01px; text-indent: 0.01px;
text-overflow: ''; text-overflow: '';
-webkit-appearance: button; -webkit-appearance: button;
/* hide default arrow in chrome OSX */ /* hide default arrow in chrome OSX */
-webkit-appearance: none; -webkit-appearance: none;
} }
.custom-dropdown::before, .custom-dropdown::before,
.custom-dropdown::after { .custom-dropdown::after {
content: ""; content: "";
position: absolute; position: absolute;
pointer-events: none; pointer-events: none;
} }
.custom-dropdown::after { .custom-dropdown::after {
/* Custom dropdown arrow */ /* Custom dropdown arrow */
content: "\25BC"; content: "\25BC";
height: 1em; height: 1em;
font-size: .625em; font-size: .625em;
line-height: 1; line-height: 1;
right: 1.2em; right: 1.2em;
top: 50%; top: 50%;
margin-top: -.5em; margin-top: -.5em;
} }
.custom-dropdown::before { .custom-dropdown::before {
/* Custom dropdown arrow cover */ /* Custom dropdown arrow cover */
width: 2em; width: 2em;
right: 0; right: 0;
top: 0; top: 0;
bottom: 0; bottom: 0;
border-radius: 0 3px 3px 0; border-radius: 0 3px 3px 0;
} }
.custom-dropdown select[disabled] { .custom-dropdown select[disabled] {
color: rgba(0, 0, 0, .3); color: rgba(0, 0, 0, .3);
} }
.custom-dropdown select[disabled]::after { .custom-dropdown select[disabled]::after {
color: rgba(0, 0, 0, .1); color: rgba(0, 0, 0, .1);
} }
.custom-dropdown::before { .custom-dropdown::before {
background-color: rgba(0, 0, 0, .15); background-color: rgba(0, 0, 0, .15);
} }
.custom-dropdown::after { .custom-dropdown::after {
color: rgba(0, 0, 0, .4); color: rgba(0, 0, 0, .4);
} }
.button-save { .button-save {
background-color: #5e18eb; background-color: #5e18eb;
color: #fff; color: #fff;
font-size: inherit; font-size: inherit;
padding: 0.5em; padding: 0.5em;
padding-right: -0.5em; padding-right: -0.5em;
border: 0; border: 0;
margin: 0; margin: 0;
border-radius: 3px; border-radius: 3px;
text-indent: 0.01px; text-indent: 0.01px;
text-overflow: ''; text-overflow: '';
-webkit-appearance: button; -webkit-appearance: button;
cursor: pointer; cursor: pointer;
} }
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap');
.expiramental { .expiramental {
font-family: 'Roboto', sans-serif; font-family: 'Roboto', sans-serif;
font-size: 10px; font-size: 10px;
color: rgb(184, 0, 0); color: rgb(184, 0, 0);
font-weight: 400; font-weight: 400;
text-decoration: underline; text-decoration: underline;
} }
input[type=checkbox] { input[type=checkbox] {
height: 0; height: 0;
width: 0; width: 0;
visibility: hidden; visibility: hidden;
} }
label { label {
cursor: pointer; cursor: pointer;
/* text-indent: -10049px; */ /* text-indent: -10049px; */
width: 85px; width: 85px;
height: 37px; height: 37px;
background:#504e58; background: #504e58;
display: block; display: block;
border-radius: 100px; border-radius: 100px;
position: relative; position: relative;
} }
label:after { label:after {
content: ''; content: '';
position: absolute; position: absolute;
top: 5px; top: 5px;
left: 5px; left: 5px;
width: 35px; width: 35px;
height: 28px; height: 28px;
background: #3d3571; background: #3d3571;
border-radius: 90px; border-radius: 90px;
transition: 0.3s; transition: 0.3s;
} }
input:checked+label { input:checked+label {
background: #7967dd; background: #7967dd;
} }
input:checked+label:after { input:checked+label:after {
left: calc(100% - 5px); left: calc(100% - 5px);
transform: translateX(-100%); transform: translateX(-100%);
} }
label:active:after { label:active:after {
width: 38px; width: 38px;
} }

87
static/unv.html Normal file
View file

@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@1,700&display=swap" rel="stylesheet">
</head>
<body style="background: #26233a;">
<div style="display: flex;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
flex-direction: row;">
<button id='send-code' style="
background: #eb6f92;
border-radius: 3px;
border: transparent;
width: 268px;
font-size: 18px;
height: 69px;
cursor: pointer;
font-family: 'Roboto', sans-serif;
" > Send Verification Code </button>
<svg style="
color: white;
font-size: 10px;
width: 53px;
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12h15m0 0l-6.75-6.75M19.5 12l-6.75 6.75" />
</svg>
<input id='codeBox' type="text" placeholder='Enter the code sent to your email' style="width: 268px;
font-size: 18px;
height: 69px;
background: #1f1d2e;
border-color: #eb6f92;
border-width: 1px;
color: white;
font-style: italic;
border-radius: 6px;
text-align: center;">
<svg style="
color: white;
font-size: 10px;
width: 53px;" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12h15m0 0l-6.75-6.75M19.5 12l-6.75 6.75" />
</svg>
<button id="checkCode" style="
background: #eb6f92;
border-radius: 3px;
border: transparent;
width: 268px;
font-size: 18px;
height: 69px;
cursor: pointer;
font-family: 'Roboto', sans-serif;
"> Submit </button>
</div>
<br>
<div style="
display: flex;
align-items: center;
justify-content: center;
align-content: center;
flex-wrap: nowrap;
flex-direction: row;
color: white;
font-family: 'Roboto', sans-serif;
">
<p id='checked'></p>
</div>
<hr>
<div style="
display: flex;
align-items: center;
justify-content: center;
align-content: center;
flex-wrap: nowrap;
flex-direction: row;
color: white;
font-family: 'Roboto', sans-serif;
">
<p id='checked'>You are seeing this screen because the owner of this website has set this site to require email one time password upon entry.</p>
</div>
<script src="resources/v.js"></script>
</body>
</html>