Several major changes: Added verification system, better loading screen, added documentation, optimizations, cleanups, etc, and finally fixed Markdown.
This commit is contained in:
parent
bf0c2fb307
commit
38dde4ed38
16 changed files with 4311 additions and 4567 deletions
3
.breakpoints
Normal file
3
.breakpoints
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"files": {}
|
||||
}
|
||||
67
README.md
67
README.md
|
|
@ -2,50 +2,31 @@
|
|||
<div align=center>
|
||||
<img src='https://nebulaproxy.nebula.bio/images/logo.png' width="100px" height="100px">
|
||||
<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>
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- Stunning UI with multiple themes
|
||||
- Stunning highly functional UI with multiple themes
|
||||
- XOR/b64 Encrypts all traffic sent from Nebula
|
||||
- Hides your IP from sites
|
||||
- [List of officially supported sites](https://github.com/NebulaServices/Nebula/blob/main/docs/officially-supported-sites.md)
|
||||
- *limited* mobile support
|
||||
- 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
|
||||
|
||||
## Quick Deployment Options
|
||||
Table of contents
|
||||
- Quick & easy deployment
|
||||
- how to use email OTP Verification mode
|
||||
- Advanced Deployment
|
||||
|
||||
|
||||
## Quick & Easy Deployment Options
|
||||
[](https://heroku.com/deploy/?template=https://github.com/NebulaServices/Nebula)
|
||||
<br>
|
||||
[](https://replit.com/github/NebulaServices/Nebula)
|
||||
|
|
@ -63,6 +44,13 @@ For support, email chloe@nebula.bio or join our discord: discord.nebula.bio
|
|||
[](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
|
||||
|
||||
### 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*
|
||||
(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
|
||||
|
||||
- [UV (one of the back-end proxy we use)](https://github.com/titaniumnetwork-dev/Ultraviolet)
|
||||
|
|
|
|||
148
app.js
148
app.js
|
|
@ -1,54 +1,142 @@
|
|||
import createBareServer from '@tomphttp/bare-server-node';
|
||||
import http from 'http';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname, join } from 'path';
|
||||
import serveStatic from 'serve-static';
|
||||
import createBareServer from "@tomphttp/bare-server-node"
|
||||
import http from "http"
|
||||
import { fileURLToPath } from "url"
|
||||
import { dirname, join } from "path"
|
||||
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;
|
||||
const bareServer = createBareServer('/bare/', {
|
||||
function getNewCode() {
|
||||
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,
|
||||
localAddress: undefined
|
||||
});
|
||||
localAddress: undefined,
|
||||
})
|
||||
|
||||
const serve = serveStatic(join(
|
||||
dirname(fileURLToPath(import.meta.url)),
|
||||
'static/'
|
||||
), {
|
||||
const serve = serveStatic(
|
||||
join(dirname(fileURLToPath(import.meta.url)), "static/"),
|
||||
{
|
||||
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 {
|
||||
|
||||
if (bareServer.shouldRoute(request)) {
|
||||
bareServer.routeRequest(request, response);
|
||||
bareServer.routeRequest(request, response)
|
||||
} else {
|
||||
serve(request, response, err => {
|
||||
let base64data
|
||||
const url = request.url
|
||||
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`)
|
||||
})
|
||||
|
||||
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"
|
||||
"Content-Type": "text/plain",
|
||||
})
|
||||
response.end(err?.stack)
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
response.writeHead(500, "Internal Server Error", {
|
||||
"Content-Type": "text/plain"
|
||||
"Content-Type": "text/plain",
|
||||
})
|
||||
response.end(e.stack)
|
||||
}
|
||||
});
|
||||
server.on('upgrade', (req, socket, head) => {
|
||||
})
|
||||
server.on("upgrade", (req, socket, head) => {
|
||||
if (bareServer.shouldRoute(req)) {
|
||||
bareServer.routeUpgrade(req, socket, head);
|
||||
bareServer.routeUpgrade(req, socket, head)
|
||||
} else {
|
||||
socket.end();
|
||||
socket.end()
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
server.listen(PORT);
|
||||
server.listen(PORT)
|
||||
|
||||
if (process.env.UNSAFE_CONTINUE)
|
||||
process.on("uncaughtException", (err, origin) => {
|
||||
|
|
@ -58,4 +146,4 @@ if (process.env.UNSAFE_CONTINUE)
|
|||
console.error()
|
||||
})
|
||||
|
||||
console.log(`Server running at http://localhost:${PORT}/.`);
|
||||
console.log(`Server running at http://localhost:${PORT}/.`)
|
||||
|
|
|
|||
7
deployment.config.json
Normal file
7
deployment.config.json
Normal 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
1
memory.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
5003
|
||||
2472
package-lock.json
generated
2472
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -17,6 +17,8 @@
|
|||
"crypto-js": "4.1.1",
|
||||
"css-tree": "^2.1.0",
|
||||
"node-fetch": "^3.2.6",
|
||||
"nodemailer": "^6.8.0",
|
||||
"nodemailer-sendgrid-transport": "^0.2.0",
|
||||
"serve-static": "^1.15.0",
|
||||
"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
1009
static/resources/cryptojs.min.js
vendored
1009
static/resources/cryptojs.min.js
vendored
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
12
static/resources/v.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +1,6 @@
|
|||
@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');
|
||||
|
||||
:root {
|
||||
--background-primary: #191724;
|
||||
--navbar-color: #26233a;
|
||||
|
|
@ -15,12 +16,12 @@
|
|||
--navbar-logo-filter: none;
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder {
|
||||
::-webkit-input-placeholder {
|
||||
text-align: center;
|
||||
font-family: 'Roboto';
|
||||
}
|
||||
|
||||
:-moz-placeholder {
|
||||
:-moz-placeholder {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
@ -35,9 +36,11 @@
|
|||
right: 0;
|
||||
background-color: var(--navbar-color);
|
||||
}
|
||||
|
||||
.sidenav-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidenav {
|
||||
height: 100%;
|
||||
width: 0;
|
||||
|
|
@ -72,9 +75,10 @@
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +91,8 @@
|
|||
width: var(--navbar-height);
|
||||
height: var(--navbar-height);
|
||||
}
|
||||
.sidenav-btn > svg {
|
||||
|
||||
.sidenav-btn>svg {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
|
@ -95,7 +100,8 @@
|
|||
#digitalCLOContainerLI {
|
||||
display: none;
|
||||
}
|
||||
#navbar > ul > li > a > svg {
|
||||
|
||||
#navbar>ul>li>a>svg {
|
||||
min-width: 24px;
|
||||
}
|
||||
}
|
||||
|
|
@ -150,7 +156,7 @@ a:hover {
|
|||
padding: 1rem;
|
||||
}
|
||||
|
||||
::placeholder,
|
||||
::placeholder,
|
||||
input[type='text'] {
|
||||
color: var(--input-placeholder-color);
|
||||
font-size: 20px;
|
||||
|
|
@ -250,6 +256,7 @@ ul li ul:hover {
|
|||
width: 0px;
|
||||
transition-duration: 0.5s;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 300px;
|
||||
transition-duration: 0.5s;
|
||||
|
|
@ -281,6 +288,7 @@ svg rect {
|
|||
0% {
|
||||
height: -20px;
|
||||
}
|
||||
|
||||
100% {
|
||||
height: 0px;
|
||||
}
|
||||
|
|
@ -318,6 +326,7 @@ body {
|
|||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
@ -352,6 +361,7 @@ input:focus::placeholder {
|
|||
cursor: default;
|
||||
|
||||
}
|
||||
|
||||
.stamp:hover {
|
||||
text-align: right;
|
||||
position: fixed;
|
||||
|
|
@ -388,6 +398,7 @@ input:focus::placeholder {
|
|||
bottom: 0;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
.modal-window {
|
||||
position: fixed;
|
||||
background-color: rgba(255, 255, 255, 0.25);
|
||||
|
|
@ -400,14 +411,17 @@ input:focus::placeholder {
|
|||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: all 0.3s;
|
||||
font-family: 'Montserrat', sans-serif;;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
;
|
||||
}
|
||||
|
||||
.modal-window:target {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.modal-window > div {
|
||||
|
||||
.modal-window>div {
|
||||
width: 400px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
|
@ -416,9 +430,11 @@ font-family: 'Montserrat', sans-serif;;
|
|||
padding: 2em;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.modal-window header {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.modal-window h1 {
|
||||
font-size: 150%;
|
||||
margin: 0 0 15px;
|
||||
|
|
@ -435,13 +451,13 @@ font-family: 'Montserrat', sans-serif;;
|
|||
width: 70px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.modal-close:hover {
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.modal-window > div {
|
||||
.modal-window>div {
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
|
|
@ -464,6 +480,7 @@ small {
|
|||
border-radius: 0.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn i {
|
||||
padding-right: 0.3em;
|
||||
}
|
||||
|
|
@ -481,6 +498,7 @@ small {
|
|||
transition: 0.2s;
|
||||
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
50% {
|
||||
opacity: 0%
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@import url("https://fonts.googleapis.com/css2?family=Work+Sans:wght@300&display=swap");
|
||||
|
||||
:root {
|
||||
--background-primary: #191724;
|
||||
--sidebar-color: #191724;
|
||||
|
|
@ -127,6 +128,7 @@ li {
|
|||
}
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Mulish:wght@300&display=swap');
|
||||
|
||||
.toogle-button {
|
||||
font-weight: bold;
|
||||
font-size: 10PX;
|
||||
|
|
@ -186,6 +188,7 @@ ul li {
|
|||
0% {
|
||||
opacity: 0.01;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
@ -195,12 +198,14 @@ ul li {
|
|||
0% {
|
||||
opacity: 0.01;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@import url('https://fonts.googleapis.com/css?family=Roboto:400,500&display=swap');
|
||||
|
||||
.notification-container {
|
||||
position: fixed;
|
||||
top: 4px;
|
||||
|
|
@ -227,6 +232,7 @@ ul li {
|
|||
opacity: 0;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
|
|
@ -300,6 +306,7 @@ ul li {
|
|||
}
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300&display=swap');
|
||||
|
||||
.settings-cont {
|
||||
background: #45454521;
|
||||
box-sizing: border-box;
|
||||
|
|
@ -336,6 +343,7 @@ ul li {
|
|||
}
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Oxygen:wght@700&display=swap');
|
||||
|
||||
.new-tag {
|
||||
font-size: 16px;
|
||||
color: rgb(226, 68, 68);
|
||||
|
|
@ -434,6 +442,7 @@ ul li {
|
|||
}
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap');
|
||||
|
||||
.expiramental {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 10px;
|
||||
|
|
@ -453,7 +462,7 @@ label {
|
|||
/* text-indent: -10049px; */
|
||||
width: 85px;
|
||||
height: 37px;
|
||||
background:#504e58;
|
||||
background: #504e58;
|
||||
display: block;
|
||||
border-radius: 100px;
|
||||
position: relative;
|
||||
|
|
|
|||
87
static/unv.html
Normal file
87
static/unv.html
Normal 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>
|
||||
Loading…
Add table
Reference in a new issue