Added relations to redis ORM

This commit is contained in:
2024-08-13 15:18:47 -04:00
parent 2a5ca3664a
commit b27e1b1617
20 changed files with 240 additions and 150 deletions
@@ -9,9 +9,9 @@ const ModelPs = require('../utils/model_pubsub');
const tldExtract = require('tld-extract').parse_host;
const providers = {
PorkBun: require('./dns_provider/porkbun'),
DigitalOcean: require('./dns_provider/digitalocean'),
Cloudflare: require('./dns_provider/cloudflare'),
DigitalOcean: require('./dns_provider/digitalocean'),
PorkBun: require('./dns_provider/porkbun'),
};
class Domain extends Table{
@@ -23,17 +23,22 @@ class Domain extends Table{
'updated_on': {default: function(){return (new Date).getTime()}, always: true},
'domain': {isRequired: true, type: 'string'},
'dnsProvider_id': {isRequired: true, type: 'string'},
'provider': {model: 'DnsProvider', rel:'one', localKey: 'dnsProvider_id'},
'zoneId': {isRequired: false, type: 'string'},
}
static async get(data, ...args){
let instance = await super.get(data, ...args);
// instance.provider = (await DnsProvider.get(instance.dnsProvider_id)).provider;
static async get(domain, ...args){
try{
domain = tldExtract(domain).domain;
}catch{}
let instance = await super.get(domain, ...args);
return instance;
}
static async getByProviderId(id){
let domains = await this.listDetail();
static async getByProviderId(id, ...args){
let domains = await this.listDetail(...args);
let results = [];
for(let domain of domains){
if(domain.dnsProvider_id == id) results.push(domain);
@@ -41,8 +46,21 @@ class Domain extends Table{
return results;
}
// toJSON(){
// return {
// ...super.toJSON(),
// provider: {
// displayName: this.provider.constructor.displayName,
// displayIconUni: this.provider.constructor.displayIconUni,
// displayIconHtml: this.provider.constructor.displayIconHtml,
// }
// }
// }
}
Domain.register(ModelPs(Domain))
class DnsProvider extends Table{
static _key = 'id';
static _keyMap = {
@@ -53,7 +71,7 @@ class DnsProvider extends Table{
'id': {default: ()=>crypto.randomBytes(8).toString("hex")},
'name': {isRequired: true, type: 'string'},
'dnsProvider': {isRequired: true, type: 'string'},
'zoneId': {isRequired: false, type: 'string'},
'domains': {model:'Domain', rel: 'many', remoteKey: 'dnsProvider_id'}
}
static __intraModel(provider){
@@ -74,23 +92,16 @@ class DnsProvider extends Table{
static async create(data, ...args){
let __intraModel = this.__intraModel(data.dnsProvider)
let provider = new __intraModel.Provider(data);
let res = await provider.listDomains();
let provider = new __intraModel.Provider(data, ...args);
let instance = await super.create.call(__intraModel, data);
if(data.noUpdate !== false) await instance.updateDomains();
return instance;
return await super.create.call(__intraModel, data, ...args);
}
static async get(data, ...args){
let instance = await super.get(data);
let instance = await super.get(data, ...args);
let __intraModel = this.__intraModel(instance.dnsProvider)
instance = await super.get.call(__intraModel, data);
instance.provider = new __intraModel.Provider(instance);
return instance;
return await super.get.call(__intraModel, data, ...args);
}
static listProviders(){
@@ -138,24 +149,33 @@ class DnsProvider extends Table{
toJSON(){
return {
...super.toJSON(),
displayName: this.provider.constructor.displayName,
displayIconHtml: this.provider.constructor.displayIconHtml,
displayIconUni: this.provider.constructor.displayIconUni,
...this.constructor.Provider.toJSON()
};
}
}
Domain = ModelPs(Domain);
DnsProvider = ModelPs(DnsProvider);
DnsProvider.register(ModelPs(DnsProvider))
module.exports = {Domain, DnsProvider};
if(require.main === module){(async function(){try{
const conf = require('../conf');
console.log(Table.models)
// console.log(await Domain.listDetail())
// console.log(JSON.stringify(await Domain.get('ipa.wtf'), null, 2))
// console.log(JSON.stringify(await Domain.listDetail() ,null, 2))
console.log(JSON.stringify(await Table.models.DnsProvider.listDetail() ,null, 2))
// console.log(await Domain.getByProviderId('e8443e03ac503c7b'));
// console.log(aw)
process.exit(0)
}catch(error){
console.log('IIFE Error:', error);
}})()}
+7 -6
View File
@@ -1,28 +1,29 @@
'use strict';
const axios = require('axios');
const {dnsErrors} = require('./common');
const {dnsErrors, DnsApi} = require('./common');
//like the options obj will always use domain data and type
// change content to data
// change name to domain
class CloudFlare{
class CloudFlare extends DnsApi{
static _keyMap = {
token: {isRequired: true, type: 'string', isPrivate: true, displayName: 'API Token'},
}
static displayName = 'CloudFlare'
static displayIconHtml = `
<svg width="32px" height="32px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<circle cx="512" cy="512" r="512" style="fill:#0080ff"/>
<path d="m273.8 669.2-.1-63.7h63.7v63.7h76v-98.8h98.8v98.5c105.1-.1 186.2-104.1 146.1-214.6-14.9-40.9-47.6-73.6-88.5-88.4-110.7-40.2-214.7 41.2-214.7 146.3H256c0-167.5 161.8-298 337.4-243.2 76.8 24 137.7 84.9 161.6 161.6C809.9 606.2 679.4 768 511.9 768v-98.8h-98.6v75.9h-75.9v-75.9h-63.6z" style="fill:#fff"/>
</svg>`
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<circle cx="512" cy="512" r="512" style="fill:#f38020"/>
<path d="M608.2 592.4c3.1-10.8 1.9-20.7-3.3-28.1-4.8-6.7-12.9-10.6-22.6-11.1l-184.7-2.4c-1.1 0-2.2-.6-2.8-1.5-.6-.9-.7-2.1-.4-3.3.6-1.8 2.4-3.2 4.3-3.3l186.4-2.4c22.1-1 46.1-18.9 54.5-40.8l10.6-27.8c.5-1.2.6-2.4.3-3.6-12-54.3-60.5-94.8-118.4-94.8-53.4 0-98.7 34.5-114.9 82.4-10.5-7.8-23.9-12-38.3-10.6-25.7 2.5-46.2 23.1-48.8 48.8-.6 6.6-.1 13.1 1.4 19.1-41.9 1.2-75.3 35.4-75.3 77.6 0 3.7.3 7.5.8 11.2.3 1.8 1.8 3.1 3.6 3.1h340.9c1.9 0 3.8-1.4 4.3-3.3l2.4-9.2zM667 473.7c-1.6 0-3.4 0-5.1.2-1.2 0-2.2.9-2.7 2.1l-7.2 25c-3.1 10.8-2 20.7 3.3 28.1 4.8 6.7 12.9 10.6 22.7 11.1l39.3 2.4c1.2 0 2.3.6 2.8 1.5.6.9.7 2.3.5 3.3-.6 1.8-2.4 3.2-4.4 3.3l-41 2.4c-22.2 1-46 18.9-54.5 40.8l-3 7.6c-.6 1.5.5 3 2.1 3h140.8c1.6 0 3.1-1 3.6-2.7 2.4-8.7 3.7-17.9 3.7-27.3 0-55.5-45.3-100.8-101-100.8" style="fill:#fff"/>
</svg>`
// Cloud icon for cloudflare
static displayIconUni = '&#xf0c2;'
constructor(token){
super()
this.token = token.token || token;
}
+46 -1
View File
@@ -19,7 +19,52 @@ let dnsErrors = {
},
}
class DnsApi{
errors = {
unauthorized(instance){
let error = new Error('UnauthorizedDnsApi');
error.name = 'UnauthorizedDnsApi';
error.message = `Unauthorized call to ${instance.constructor ? instance.constructor.name : instance.name}`;
error.status = 424;
return error;
},
other(instance, status, message){
let error = new Error('OtherDnsApiError');
error.name = 'OtherDnsApiError';
error.message = `DNS API Error ${instance.constructor ? instance.constructor.name : instance.name}: `;
error.status = 424;
return error;
},
}
static info(){
let svgDataUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(this.displayIconHtml)
.replace(/'/g, '%27')
.replace(/"/g, '%22')}`
return {
displayName: this.displayName,
displayIconUni: this.displayIconUni,
displayIconHtml: svgDataUrl,
fields: this._keyMap,
}
}
static toJSON(){
return {
...this.info(),
}
}
toJSON(){
return this.constructor.toJSON()
}
}
module.exports = {
dnsErrors
dnsErrors,
DnsApi,
};
+4 -3
View File
@@ -1,16 +1,16 @@
'use strict';
const axios = require('axios');
const {dnsErrors} = require('./common');
const {dnsErrors, DnsApi} = require('./common');
class DigitalOcean{
class DigitalOcean extends DnsApi{
static _keyMap = {
token: {isRequired: true, type: 'string', isPrivate: true, displayName: 'API Token'},
}
static displayName = 'DigitalOcean'
static displayIconHtml = `
<svg width="32px" height="32px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<svg height="100%" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<circle cx="512" cy="512" r="512" style="fill:#0080ff"/>
<path d="m273.8 669.2-.1-63.7h63.7v63.7h76v-98.8h98.8v98.5c105.1-.1 186.2-104.1 146.1-214.6-14.9-40.9-47.6-73.6-88.5-88.4-110.7-40.2-214.7 41.2-214.7 146.3H256c0-167.5 161.8-298 337.4-243.2 76.8 24 137.7 84.9 161.6 161.6C809.9 606.2 679.4 768 511.9 768v-98.8h-98.6v75.9h-75.9v-75.9h-63.6z" style="fill:#fff"/>
</svg>`
@@ -18,6 +18,7 @@ class DigitalOcean{
static displayIconUni = '&#xf391;'
constructor(token){
super()
this.token = token.token || token;
}
+7 -9
View File
@@ -1,18 +1,19 @@
'use strict';
const axios = require('axios');
const {dnsErrors} = require('./common');
const {dnsErrors, DnsApi} = require('./common');
class PorkBun{
class PorkBun extends DnsApi{
static _keyMap = {
'apiKey': {isRequired: true, type: 'string', isPrivate: true, displayName: 'API key'},
'secretApiKey': {isRequired: true, type: 'string', isPrivate: true, displayName: 'API Secret key'},
}
static displayName = 'DigitalOcean';
static displayName = 'PorkBun';
static displayIconUni = '&#xf7e5';
static displayIconHtml = `
<svg width="32px" height="32px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<style>
.st1{fill:#fff}
</style>
@@ -24,12 +25,9 @@ class PorkBun{
</g>
</g>
</svg>`
// '<i class="fa-solid fa-bacon"></i>';
static displayIconUni = '&#xf7e5';
baseUrl = 'https://api.porkbun.com/api/json/v3';
constructor(args){
super()
this.apiKey = args.apiKey;
this.secretApiKey = args.secretApiKey;
}
@@ -42,7 +40,7 @@ class PorkBun{
secretapikey: this.secretApiKey,
apikey: this.apiKey,
};
res = await axios.post(`${this.baseUrl}${url}`, data);
res = await axios.post(`'https://api.porkbun.com/api/json/v3'${url}`, data);
return res;
}catch(error){
+3 -7
View File
@@ -1,18 +1,12 @@
'use strict';
const Table = require('../utils/redis_model');
const Table = require('.');
const ModelPs = require('../utils/model_pubsub');
const tldExtract = require('tld-extract').parse_host;
const PorkBun = require('./dns_provider/porkbun');
const LetsEncrypt = require('../utils/letsencrypt');
const conf = require('../conf');
// let porkBun = new PorkBun(conf.porkBun.apiKey, conf.porkBun.secretApiKey);
// let letsEncrypt = new LetsEncrypt({
// directoryUrl: LetsEncrypt.AcmeClient.directory.letsencrypt.staging,
// });
class Host extends Table{
static _key = 'host';
@@ -31,6 +25,7 @@ class Host extends Table{
'wildcard_status': {isRequired: false, type: 'string', min: 3, max: 500, default: 'Requesting'},
'wildcard_parent': {isRequired: false, type: 'string', min: 3, max: 500},
'wildcard_expires': {isRequired: false, type: 'number'},
'domain': {model: 'Domain', rel: 'one'},
}
static lookUpObj = {};
@@ -322,6 +317,7 @@ class Host extends Table{
return true;
}
}
Host.register(ModelPs(Host))
class Cached extends Table{
+9
View File
@@ -0,0 +1,9 @@
'use strict';
const Table = require('../utils/redis_model')
module.exports = Table;
require('./dns_provider');
require('./host');
require('./token');
require('./user');
+10 -11
View File
@@ -1,7 +1,6 @@
'use strict';
const Table = require('../utils/redis_model');
const {User} = require('./user');
const Table = require('.');
const UUID = function b(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,b)};
@@ -11,8 +10,8 @@ class Token extends Table{
'created_by': {isRequired: true, type: 'string', min: 3, max: 500},
'created_on': {default: function(){return (new Date).getTime()}},
'updated_on': {default: function(){return (new Date).getTime()}, always: true},
'token': {default: UUID, type: 'string', min: 36, max: 36},
'is_valid': {default: true, type: 'boolean'}
'token': {default: UUID, type: 'string', min: 36, max: 36, isPrivate: true},
'is_valid': {default: true, type: 'boolean'},
}
constructor(...args){
@@ -28,13 +27,12 @@ class Token extends Table{
}
}
class AuthToken extends Token{
constructor(...args){
super(...args);
}
Token.register();
async getUser(){
return await User.get(this.created_by);
class AuthToken extends Token{
static _keyMap = {
...super._keyMap,
user: {model: 'User', rel: 'one', localKey: 'created_by'},
}
static async create(data){
@@ -42,8 +40,8 @@ class AuthToken extends Token{
return super.create(data)
}
}
AuthToken.register();
class InviteToken extends Token{
static _keyMap = {
@@ -66,5 +64,6 @@ class InviteToken extends Token{
}
}
}
InviteToken.register();
module.exports = {Token, InviteToken, AuthToken};
+1 -4
View File
@@ -58,12 +58,9 @@ class User extends Table{
throw error;
}
};
}
module.exports = {User};
User.register();
(async function(){
var defaultUser = 'proxyadmin2'