domain registration, start on DNS
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
node_modules
|
||||
ndm.db
|
||||
*.env
|
||||
@@ -68,6 +68,86 @@ body {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.InsetContentBox {
|
||||
border: 1px inset;
|
||||
min-height: 200px;
|
||||
background-color: white;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.ContentBox {
|
||||
border: 2px solid #4682b4;
|
||||
min-height: 200px;
|
||||
background-color: white;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#DomainOptions {
|
||||
text-align: center;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#DomainSelection {
|
||||
overflow: scroll;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
#DomainSelection li:hover {
|
||||
background-color: #2e69cb;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.SelectedListItem {
|
||||
background-color: #2e69cb;
|
||||
color: white;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.MutedText {
|
||||
color: #afafaf;
|
||||
}
|
||||
|
||||
.TitleText {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.Hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #800000;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0000ee;
|
||||
}
|
||||
|
||||
.DefaultButton {
|
||||
background-color: #f5cd2f;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.VerticalInputForm {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// This script is designed to support at a minimum IE 6
|
||||
//
|
||||
// All menu functions are defined outside of initMenu.
|
||||
//
|
||||
// This is so I'm not duplicating functions between-
|
||||
// checks for what browser we have
|
||||
|
||||
function resetSelection() {
|
||||
var elements = document.getElementsByName("domain_selection");
|
||||
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
(function(li) {
|
||||
li.className = "";
|
||||
|
||||
|
||||
})(elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSelection(li) {
|
||||
var domainId = li.value;
|
||||
var editDNS = document.getElementById("options_edit_dns");
|
||||
var unreg = document.getElementById("options_unregister");
|
||||
|
||||
if(li.className == "SelectedListItem") {
|
||||
editDNS.className = "Hidden";
|
||||
unreg.className = "Hidden";
|
||||
li.className = "";
|
||||
return;
|
||||
}
|
||||
|
||||
resetSelection();
|
||||
|
||||
li.className = "SelectedListItem";
|
||||
|
||||
|
||||
|
||||
editDNS.className = "";
|
||||
editDNS.href = "/dns/edit/" + domainId;
|
||||
|
||||
unreg.className = "";
|
||||
unreg.href = "/domains/unregister/" + domainId;
|
||||
}
|
||||
|
||||
// Once the page has fully loaded, connect each button to its code
|
||||
function initDomainSelection() {
|
||||
// Register selection events
|
||||
var elements = document.getElementsByName("domain_selection");
|
||||
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
(function(li) {
|
||||
if(window.addEventListener) {
|
||||
li.addEventListener("click", function() {
|
||||
toggleSelection(li);
|
||||
});
|
||||
} else {
|
||||
li.attachEvent("onclick", function() {
|
||||
toggleSelection(li);
|
||||
});
|
||||
}
|
||||
})(elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Register load / onload event
|
||||
if(window.addEventListener) {
|
||||
window.addEventListener('load', initDomainSelection);
|
||||
} else if(window.attachEvent) {
|
||||
window.attachEvent('onload', initDomainSelection);
|
||||
} else {
|
||||
alert("Unsupported browser.");
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
function FQDNToCoreDNSPath(fqdn) {
|
||||
|
||||
}
|
||||
|
||||
function RegisterNewDomain(domainLabel) {
|
||||
|
||||
}
|
||||
|
||||
function GetAllRecords() {
|
||||
|
||||
}
|
||||
|
||||
function CreateARecord(domain, host) {
|
||||
|
||||
}
|
||||
|
||||
function DeleteARecord(domain, host) {
|
||||
|
||||
}
|
||||
|
||||
function UpdateARecord(domain, host) {
|
||||
|
||||
}
|
||||
|
||||
function CreateMXRecord(domain, host) {
|
||||
|
||||
}
|
||||
|
||||
function DeleteMXRecord(domain, host) {
|
||||
|
||||
}
|
||||
|
||||
function UpdateMXRecord(domain, host) {
|
||||
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
RegisterNewDomain,
|
||||
GetAllRecords,
|
||||
CreateARecord,
|
||||
DeleteARecord
|
||||
}
|
||||
+12
-2
@@ -34,13 +34,23 @@ const User = seqConn.define('User', {
|
||||
const RegisteredDomain = seqConn.define('RegisteredDomain', {
|
||||
domain: {
|
||||
type: Sequelize.TEXT,
|
||||
unique: true,
|
||||
allowNull: false
|
||||
},
|
||||
tld: {
|
||||
type: Sequelize.TEXT,
|
||||
allowNull: false
|
||||
},
|
||||
owner: {
|
||||
type: Sequelize.BIGINT.UNSIGNED,
|
||||
allowNull: false
|
||||
}
|
||||
},
|
||||
}, {
|
||||
indexes: [
|
||||
{
|
||||
unique: true,
|
||||
fields: ['domain', 'tld'],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
////// Exports //////
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const domainValidator = require('../validators/domain');
|
||||
const authMw = require('../session');
|
||||
const database = require('../database.js');
|
||||
const dbConnection = database.db;
|
||||
const Sequelize = require('sequelize');
|
||||
const pageTitle = 'Domain Manager | Edit DNS';
|
||||
|
||||
|
||||
// Manage domains
|
||||
router.get('/dns/edit/:domainId', authMw.AllowIfAuthenticated, async (req, res, next) => {
|
||||
const result = await dbConnection.transaction(async(t) => {
|
||||
const ownedDomain = await database.models.RegisteredDomain.findOne({
|
||||
where: {
|
||||
id: req.params.domainId,
|
||||
owner: req.session.userId
|
||||
}
|
||||
}, {transaction: t});
|
||||
|
||||
return ownedDomain;
|
||||
});
|
||||
|
||||
if(!result)
|
||||
return next();
|
||||
|
||||
res.render('dns', {title: pageTitle, domain: result});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -0,0 +1,86 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const domainValidator = require('../validators/domain');
|
||||
const authMw = require('../session');
|
||||
const database = require('../database.js');
|
||||
const dbConnection = database.db;
|
||||
const Sequelize = require('sequelize');
|
||||
const pageTitle = 'Domain Manager | Register New Domain';
|
||||
|
||||
const supportedTLDs = [
|
||||
"local",
|
||||
"tomato",
|
||||
"secret",
|
||||
"money",
|
||||
"lol",
|
||||
"lmao"
|
||||
];
|
||||
|
||||
// Manage domains
|
||||
router.get('/domains', authMw.AllowIfAuthenticated, async (req, res) => {
|
||||
const result = await dbConnection.transaction(async(t) => {
|
||||
const ownedDomains = await database.models.RegisteredDomain.findAll({
|
||||
where: {
|
||||
owner: req.session.userId
|
||||
}
|
||||
}, {transaction: t});
|
||||
|
||||
return ownedDomains;
|
||||
});
|
||||
|
||||
let registeredDomains = result;
|
||||
|
||||
res.render('domains', {title: 'Domain Manager | Your Domains', registeredDomains: registeredDomains});
|
||||
});
|
||||
|
||||
//// Register domains ////
|
||||
|
||||
// GET
|
||||
// Frontend page to register a new domain
|
||||
router.get('/domains/new', authMw.AllowIfAuthenticated, async(req, res) => {
|
||||
res.render('newdomain', {title: 'Domain Manager | Register Domain', supportedTLDs: supportedTLDs});
|
||||
});
|
||||
|
||||
// POST
|
||||
// Backend post handler to register the domain
|
||||
router.post('/domains/new', authMw.AllowIfAuthenticated, async(req, res, next) => {
|
||||
const reqBody = req.body;
|
||||
const validationResult = domainValidator.test(reqBody);
|
||||
const validationError = validationResult.error;
|
||||
let errors = [];
|
||||
|
||||
if(validationError !== undefined)
|
||||
errors = validationError.details;
|
||||
|
||||
try {
|
||||
if(errors.length === 0) {
|
||||
const result = await dbConnection.transaction(async(t) => {
|
||||
const newDomain = await database.models.RegisteredDomain.create({
|
||||
domain: reqBody.register_domain_label,
|
||||
tld: reqBody.register_domain_tld,
|
||||
owner: req.session.userId
|
||||
}, {transaction: t});
|
||||
|
||||
return newDomain;
|
||||
});
|
||||
|
||||
if(result !== undefined) {
|
||||
return res.redirect('/domains');
|
||||
} else {
|
||||
errors.push({message: 'Failed to register new domain.'})
|
||||
}
|
||||
}
|
||||
} catch(error) {
|
||||
if(error instanceof Sequelize.UniqueConstraintError) {
|
||||
errors.push({message: 'Domain is not available.'});
|
||||
} else {
|
||||
error.status = 500;
|
||||
return next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// if we're here we failed, I specify true for csrfToken to force reset it
|
||||
return res.render('newdomain', {title: pageTitle, supportedTLDs: supportedTLDs, errors: errors, csrfToken: req.csrfToken(true) });
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -0,0 +1,11 @@
|
||||
const Joi = require('joi');
|
||||
const domainRegistrySchema = Joi.object().keys({
|
||||
register_domain_label: Joi.string().alphanum().min(1).max(63).required(),
|
||||
register_domain_tld: Joi.string().valid("local", "tomato", "secret", "money", "lol", "lmao").required()
|
||||
}).unknown(true);
|
||||
|
||||
module.exports = {
|
||||
test: (body) => {
|
||||
return domainRegistrySchema.validate(body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>Configuring DNS records for {{domain.domain}}.{{domain.tld}}</p>
|
||||
@@ -0,0 +1,34 @@
|
||||
{{{getScript "/scripts/domainmgmt.js" nonce}}}
|
||||
|
||||
<p>Manage your registered domains</p>
|
||||
|
||||
{{#if errors}}
|
||||
<ul>
|
||||
{{#each errors}}
|
||||
<li>{{this.message}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
|
||||
<div class="InsetContentBox" id="DomainSelection">
|
||||
<div style="width: 600px;"></div>
|
||||
<ul>
|
||||
{{#if (lenEq registeredDomains 0)}}
|
||||
<li class="MutedText">You don't currently have any registered domains</li>
|
||||
{{else}}
|
||||
{{#each registeredDomains}}
|
||||
<li name="domain_selection" value="{{this.id}}">{{this.domain}}.{{this.tld}}</li>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="ContentBox" id="DomainOptions">
|
||||
<div style="width: 200px;"></div>
|
||||
<p class="TitleText">Options</p>
|
||||
<ul>
|
||||
<li><a href="/domains/new">Register New Domain</a></li>
|
||||
<li><a class="Hidden" href="/dns/edit" id="options_edit_dns">Edit DNS</a></li>
|
||||
<li><a class="Hidden" href="/domains/unregister" id="options_unregister">Unregister Domain</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -16,33 +16,32 @@
|
||||
{{/if}}
|
||||
|
||||
<div id="PageContent">
|
||||
<div id="Logo">
|
||||
<p>Domain Manager</p>
|
||||
</div>
|
||||
<div id="Header">
|
||||
<div id="Header-Left">
|
||||
<a href="/">Home</a>
|
||||
{{#if isLoggedIn}}
|
||||
<span>|</span>
|
||||
<a href="/dns">DNS</a>
|
||||
<span>|</span>
|
||||
<a href="/domains">Domains</a>
|
||||
{{/if}}
|
||||
<div id="Logo">
|
||||
<p>Domain Manager</p>
|
||||
</div>
|
||||
<div id="Header">
|
||||
<div id="Header-Left">
|
||||
<a href="/">Home</a>
|
||||
{{#if isLoggedIn}}
|
||||
<span>|</span>
|
||||
<a href="/domains">Domains</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div id="Header-Right">
|
||||
{{#unless isLoggedIn}}
|
||||
<a href="/login">Login</a>
|
||||
<span>|</span>
|
||||
<a href="/register">Register</a>
|
||||
{{else}}
|
||||
<span>{{username}}</span>
|
||||
<span>|</span>
|
||||
<a id="Menu_Auth_Logout" href="javascript://void();">Logout</a>
|
||||
{{/unless}}
|
||||
<div id="Header-Right">
|
||||
{{#unless isLoggedIn}}
|
||||
<a href="/login">Login</a>
|
||||
<span>|</span>
|
||||
<a href="/register">Register</a>
|
||||
{{else}}
|
||||
<span>{{username}}</span>
|
||||
<span>|</span>
|
||||
<a id="Menu_Auth_Logout" href="javascript://void();">Logout</a>
|
||||
{{/unless}}
|
||||
</div>
|
||||
<br>
|
||||
<hr>
|
||||
</div>
|
||||
<br>
|
||||
<hr>
|
||||
|
||||
{{{body}}}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<p>Register a new domain</p>
|
||||
|
||||
{{#if errors}}
|
||||
<ul>
|
||||
{{#each errors}}
|
||||
<li>{{this.message}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
|
||||
<form action="/domains/new" method="post">
|
||||
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
||||
<input type="text" name="register_domain_label">
|
||||
<select name="register_domain_tld">
|
||||
{{#each supportedTLDs}}
|
||||
<option value="{{this}}">.{{this}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
<br><br>
|
||||
<input type="submit" class="DefaultButton" value="Register">
|
||||
</form>
|
||||
Reference in New Issue
Block a user