├── .gitignore ├── cloudflare.js ├── config.default.js ├── database.js ├── index.js ├── package-lock.json ├── package.json ├── readme.md ├── send.js └── static ├── css ├── style.css └── style.min.css ├── index.html ├── js ├── bundle.js └── bundle.min.js └── svg └── link.svg /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | config.js 3 | db.db 4 | *.sh -------------------------------------------------------------------------------- /cloudflare.js: -------------------------------------------------------------------------------- 1 | const fetch=require("node-fetch"); 2 | var zone_id,headers; 3 | async function get(url){ 4 | return await fetch(url,{headers}).then(res=>res.json()); 5 | } 6 | async function post(url,body,method='POST'){ 7 | return await fetch(url,{ 8 | headers,method, 9 | body:JSON.stringify(body) 10 | }).then(res=>res.json()); 11 | } 12 | async function ask(record_name){ 13 | return await get(`https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records?name=${record_name}`) 14 | } 15 | async function add({type,name,content,ttl=1}){ 16 | return await post( 17 | `https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records`, 18 | {type,name,content,ttl} 19 | ) 20 | } 21 | async function update({id,type,name,content,ttl=1}){ 22 | var body={id,type,name,content}; 23 | return await post( 24 | `https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records/${id}`, 25 | body,'PUT' 26 | ) 27 | } 28 | async function del({id}){ 29 | return await post( 30 | `https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records/${id}`,null,'DELETE' 31 | ) 32 | } 33 | module.exports=async({zone_name,email,key})=>{ 34 | headers={ 35 | "X-Auth-Email":email,"X-Auth-Key":key, 36 | "Content-Type":"application/json" 37 | } 38 | res=await get(`https://api.cloudflare.com/client/v4/zones?name=${zone_name}`); 39 | zone_id=res.result[0].id; 40 | return {zone_id,ask,add,update,del}; 41 | } -------------------------------------------------------------------------------- /config.default.js: -------------------------------------------------------------------------------- 1 | module.exports={ 2 | cf:{ // cloudflare api配置 3 | email:'zcmimi@outlook.com', 4 | key:'*************************************', 5 | zone_name:'kksk.best' 6 | }, 7 | mailer:{ // cloudflare api配置 8 | mailer:{ 9 | host:"smtp.office365.com", 10 | port:587, 11 | auth:{ 12 | user: "zcmimi@outlook.com", 13 | pass: "*****************" 14 | } 15 | }, 16 | from: "zcmimi" 17 | }, 18 | limit:{ // 限制 19 | per:3, // 每个邮箱最多享有几个二级域名 20 | minLength:3, // 二级域名前缀最小长度 21 | block:[] // 禁止注册的前缀 22 | }, 23 | tips:{ // 提示 24 | WrongToken:'Wrong token!', 25 | WrongMaster:'This name has been registered by someone else', 26 | Accepted:'Accepted', 27 | Failed:'Failed', 28 | QuotaExceeded:'Quota exceeded!', 29 | IllegalName:'Illegal name!' 30 | } 31 | } -------------------------------------------------------------------------------- /database.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const Database=require("better-sqlite3"); 3 | var DB=new Database('./db.db'); 4 | // DB.prepare("DROP TABLE records").run(); 5 | DB.prepare("CREATE TABLE IF NOT EXISTS records (id,type,name,content,ttl,json,email)").run(); 6 | const records={ 7 | _ins:DB.prepare("INSERT INTO records (id,type,name,content,ttl,json,email) VALUES (?,?,?,?,?,?,?)"), 8 | ins(id,type,name,content,ttl,json,email){this._ins.run(id,type,name,content,ttl,json,email);}, 9 | _upd:DB.prepare("UPDATE records SET type=?,name=?,content=?,ttl=?,json=?,email=? WHERE id=?"), 10 | upd(id,type,name,content,ttl,json,email){this._upd.run(type,name,content,ttl,json,email,id);}, 11 | _qry:DB.prepare("SELECT * FROM records WHERE id=?"), 12 | qry(id){return this._qry.get(id);}, 13 | select(email){return DB.prepare("SELECT * FROM records WHERE email=?").all(email);}, 14 | select_name(name){return DB.prepare("SELECT * FROM records WHERE name=?").all(name);}, 15 | del(id){return DB.prepare("DELETE FROM records WHERE id=?").run(id);}, 16 | _count:DB.prepare("SELECT COUNT(DISTINCT name) AS num FROM records WHERE email=?"), 17 | count(email){return this._count.get(email).num;} 18 | } 19 | 20 | DB.prepare("CREATE TABLE IF NOT EXISTS tokens (email,token)").run(); 21 | const tokens={ 22 | _ins:DB.prepare("INSERT INTO tokens (email,token) VALUES (?,?)"), 23 | ins(email,token){this._ins.run(email,token);}, 24 | _upd:DB.prepare("UPDATE tokens SET token=? where email=?"), 25 | upd(email,token){this._upd.run(token,email);}, 26 | _qry:DB.prepare("SELECT * FROM tokens WHERE email=?"), 27 | qry(email){return this._qry.get(email);} 28 | } 29 | DB.prepare("CREATE TABLE IF NOT EXISTS quotas (email,quota)").run(); 30 | const quotas={ 31 | _ins:DB.prepare("INSERT INTO quotas (email,quota) VALUES (?,?)"), 32 | ins(email,quota){this._ins.run(email,quota);}, 33 | _upd:DB.prepare("UPDATE quotas SET quota=? where email=?"), 34 | upd(email,quota){this._upd.run(quota,email);}, 35 | _qry:DB.prepare("SELECT * FROM quotas WHERE email=?"), 36 | qry(email){return this._qry.get(email);} 37 | } 38 | module.exports={ 39 | records,tokens,quotas 40 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | const port=process.env.PORT||1191,host=process.env.HOST||''; 3 | const express=require('express'), 4 | bp=require('body-parser'), 5 | fs=require("fs"), 6 | db=require("./database"); 7 | var config=require('./config'), 8 | send=require('./send')(config.mailer), 9 | cf; 10 | require('./cloudflare')(config.cf).then(CF=>{ 11 | cf=CF; 12 | console.log(cf); 13 | }); 14 | 15 | function genToken(len=10){return Math.random().toString(16).slice(-len);} 16 | 17 | var svr=express(); 18 | svr.server=svr.listen(port,host,()=>{ 19 | console.log(`server running @ http://${host ? host : 'localhost'}:${port}`); 20 | }); 21 | svr.use(bp.urlencoded({extended: false})); 22 | svr.use(bp.json()); 23 | svr.use(require("cookie-parser")()); 24 | svr.use(express.static("./static")); 25 | 26 | svr.all('*',(req,res,nxt)=>{ 27 | // if(req.body)console.log(req.body); 28 | nxt(); 29 | }); 30 | 31 | function pr(status,data){return {status,data};} 32 | function chkToken(email,token){ 33 | var t=db.tokens.qry(email); 34 | return t&&t.token==token; 35 | } 36 | 37 | svr.post("/api/sendToken",async(req,res)=>{ 38 | var email=req.body.email,t=db.tokens.qry(email),token; 39 | if(!t){ 40 | token=genToken(); 41 | db.tokens.ins(email,token); 42 | } 43 | else if(req.body.re){ 44 | token=genToken(); 45 | db.tokens.upd(email,token); 46 | } 47 | else token=t.token; 48 | try{ 49 | var t=await send.sendToken(req.body.email,token); 50 | res.send(pr(1,'Sent successfully!')); 51 | } 52 | catch(e){res.send(pr(0,{error:e}));} 53 | }); 54 | svr.get("/api/zone_name",async(req,res)=>{res.send(config.cf.zone_name)}); 55 | svr.post("/api/chkToken",async(req,res)=>{ 56 | var {email,token}=req.body; 57 | if(!chkToken(email,token))res.send(pr(0,{error:config.tips.WrongToken})); 58 | else res.send(pr(1,config.tips.Accepted)); 59 | }); 60 | svr.post("/api/search",async(req,res)=>{ 61 | var t=db.records.select_name(req.body.name); 62 | res.send(pr(1,t)); 63 | }); 64 | function reachQuota(email){ 65 | var t=db.quotas.qry(email),x=t?t.quota:config.limit.per; 66 | return db.records.count(email)>=x; 67 | } 68 | var block=new Set(); 69 | for(var i of config.limit.block)block.add(i); 70 | console.log(block); 71 | function chkName(name){ 72 | var prefix=name.slice(0,name.length-config.cf.zone_name.length-1); 73 | console.log(prefix); 74 | if(prefix.length{ 79 | var {email,token,record}=req.body; 80 | if(!chkName(record.name)) 81 | return res.send(pr(0,{error:config.tips.IllegalName})); 82 | var t=db.records.select_name(record.name); 83 | console.log(t); 84 | if(t.length&&t[0].email!=email)return res.send(pr(0,{error:config.tips.WrongMaster})); 85 | if(!chkToken(email,token))return res.send(pr(0,{error:config.tips.WrongToken})); 86 | if(reachQuota(email)) 87 | return res.send(pr(0,{error:config.tips.QuotaExceeded})); 88 | var t=await cf.add(record),ret=t.result; 89 | console.log(t); 90 | if(t.success){ 91 | var {id,type,name,content,ttl}=ret; 92 | db.records.ins(id,type,name,content,ttl,JSON.stringify(ret),email); 93 | return res.send(pr(1,t)); 94 | } 95 | else return res.send(pr(0,{error:t.errors[0].message})); 96 | }); 97 | svr.post("/api/edit",async(req,res)=>{ 98 | var {email,token,record}=req.body; 99 | if(!chkName(record.name)) 100 | return res.send(pr(0,{error:config.tips.IllegalName})); 101 | if(!chkToken(email,token))return res.send(pr(0,{error:config.tips.WrongToken})); 102 | var t=db.records.select_name(record.name); 103 | if(t.length&&t[0].email!=email)return res.send(pr(0,{error:config.tips.WrongMaster})); 104 | var t=await cf.update(record),ret=t.result; 105 | console.log(t); 106 | if(t.success){ 107 | var {id,type,name,content,ttl}=ret; 108 | db.records.upd(id,type,name,content,ttl,JSON.stringify(ret),email); 109 | return res.send(pr(1,t)); 110 | } 111 | else return res.send(pr(0,{error:t.errors[0].message})); 112 | }); 113 | svr.post("/api/del",async(req,res)=>{ 114 | var {email,token,record}=req.body; 115 | var t=db.records.qry(record.id); 116 | if(!t)return res.send(pr(0,'None')); 117 | if(t.email!=email)return res.send(pr(0,{error:config.tips.WrongMaster})); 118 | if(!chkToken(email,token))return res.send(pr(0,{error:config.tips.WrongToken})); 119 | t=await cf.del(record); 120 | if(t.success){ 121 | db.records.del(record.id); 122 | res.send(pr(1,t)); 123 | } 124 | else return res.send(pr(0,{error:t.errors[0].message})); 125 | }); 126 | svr.post("/api/all",async(req,res)=>{ 127 | var {email,token}=req.body; 128 | if(!chkToken(email,token))return res.send(pr(0,{error:config.tips.WrongToken})); 129 | var t=db.records.select(email); 130 | return res.send(pr(1,t)); 131 | }); -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "share-domain", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.7", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 11 | "requires": { 12 | "mime-types": "2.1.27", 13 | "negotiator": "0.6.2" 14 | } 15 | }, 16 | "ansi-regex": { 17 | "version": "2.1.1", 18 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 19 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 20 | }, 21 | "aproba": { 22 | "version": "1.2.0", 23 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 24 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" 25 | }, 26 | "are-we-there-yet": { 27 | "version": "1.1.5", 28 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 29 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 30 | "requires": { 31 | "delegates": "1.0.0", 32 | "readable-stream": "2.3.7" 33 | } 34 | }, 35 | "array-flatten": { 36 | "version": "1.1.1", 37 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 38 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 39 | }, 40 | "base64-js": { 41 | "version": "1.5.1", 42 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 43 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" 44 | }, 45 | "better-sqlite3": { 46 | "version": "7.1.1", 47 | "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.1.1.tgz", 48 | "integrity": "sha512-AkvGGyhAVZhRBOul2WT+5CB2EuveM3ZkebEKe1wxMqDZUy1XB/1RBgM66t0ybHC4DIni8+pr7NaLqEX87NUTwg==", 49 | "requires": { 50 | "bindings": "1.5.0", 51 | "prebuild-install": "5.3.6", 52 | "tar": "4.4.10" 53 | } 54 | }, 55 | "bindings": { 56 | "version": "1.5.0", 57 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 58 | "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 59 | "requires": { 60 | "file-uri-to-path": "1.0.0" 61 | } 62 | }, 63 | "bl": { 64 | "version": "4.0.3", 65 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", 66 | "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", 67 | "requires": { 68 | "buffer": "5.7.1", 69 | "inherits": "2.0.4", 70 | "readable-stream": "3.6.0" 71 | }, 72 | "dependencies": { 73 | "inherits": { 74 | "version": "2.0.4", 75 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 76 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 77 | }, 78 | "readable-stream": { 79 | "version": "3.6.0", 80 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 81 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 82 | "requires": { 83 | "inherits": "2.0.4", 84 | "string_decoder": "1.1.1", 85 | "util-deprecate": "1.0.2" 86 | } 87 | } 88 | } 89 | }, 90 | "body-parser": { 91 | "version": "1.19.0", 92 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 93 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 94 | "requires": { 95 | "bytes": "3.1.0", 96 | "content-type": "1.0.4", 97 | "debug": "2.6.9", 98 | "depd": "1.1.2", 99 | "http-errors": "1.7.2", 100 | "iconv-lite": "0.4.24", 101 | "on-finished": "2.3.0", 102 | "qs": "6.7.0", 103 | "raw-body": "2.4.0", 104 | "type-is": "1.6.18" 105 | } 106 | }, 107 | "buffer": { 108 | "version": "5.7.1", 109 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 110 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 111 | "requires": { 112 | "base64-js": "1.5.1", 113 | "ieee754": "1.2.1" 114 | } 115 | }, 116 | "bytes": { 117 | "version": "3.1.0", 118 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 119 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 120 | }, 121 | "chownr": { 122 | "version": "1.1.4", 123 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 124 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" 125 | }, 126 | "code-point-at": { 127 | "version": "1.1.0", 128 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 129 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 130 | }, 131 | "console-control-strings": { 132 | "version": "1.1.0", 133 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 134 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" 135 | }, 136 | "content-disposition": { 137 | "version": "0.5.3", 138 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 139 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 140 | "requires": { 141 | "safe-buffer": "5.1.2" 142 | } 143 | }, 144 | "content-type": { 145 | "version": "1.0.4", 146 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 147 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 148 | }, 149 | "cookie": { 150 | "version": "0.4.0", 151 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 152 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 153 | }, 154 | "cookie-parser": { 155 | "version": "1.4.5", 156 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz", 157 | "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==", 158 | "requires": { 159 | "cookie": "0.4.0", 160 | "cookie-signature": "1.0.6" 161 | } 162 | }, 163 | "cookie-signature": { 164 | "version": "1.0.6", 165 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 166 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 167 | }, 168 | "core-util-is": { 169 | "version": "1.0.2", 170 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 171 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 172 | }, 173 | "debug": { 174 | "version": "2.6.9", 175 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 176 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 177 | "requires": { 178 | "ms": "2.0.0" 179 | } 180 | }, 181 | "decompress-response": { 182 | "version": "4.2.1", 183 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", 184 | "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", 185 | "requires": { 186 | "mimic-response": "2.1.0" 187 | } 188 | }, 189 | "deep-extend": { 190 | "version": "0.6.0", 191 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 192 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" 193 | }, 194 | "delegates": { 195 | "version": "1.0.0", 196 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 197 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" 198 | }, 199 | "depd": { 200 | "version": "1.1.2", 201 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 202 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 203 | }, 204 | "destroy": { 205 | "version": "1.0.4", 206 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 207 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 208 | }, 209 | "detect-libc": { 210 | "version": "1.0.3", 211 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", 212 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" 213 | }, 214 | "ee-first": { 215 | "version": "1.1.1", 216 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 217 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 218 | }, 219 | "encodeurl": { 220 | "version": "1.0.2", 221 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 222 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 223 | }, 224 | "end-of-stream": { 225 | "version": "1.4.4", 226 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 227 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 228 | "requires": { 229 | "once": "1.4.0" 230 | } 231 | }, 232 | "escape-html": { 233 | "version": "1.0.3", 234 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 235 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 236 | }, 237 | "etag": { 238 | "version": "1.8.1", 239 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 240 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 241 | }, 242 | "expand-template": { 243 | "version": "2.0.3", 244 | "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", 245 | "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" 246 | }, 247 | "express": { 248 | "version": "4.17.1", 249 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 250 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 251 | "requires": { 252 | "accepts": "1.3.7", 253 | "array-flatten": "1.1.1", 254 | "body-parser": "1.19.0", 255 | "content-disposition": "0.5.3", 256 | "content-type": "1.0.4", 257 | "cookie": "0.4.0", 258 | "cookie-signature": "1.0.6", 259 | "debug": "2.6.9", 260 | "depd": "1.1.2", 261 | "encodeurl": "1.0.2", 262 | "escape-html": "1.0.3", 263 | "etag": "1.8.1", 264 | "finalhandler": "1.1.2", 265 | "fresh": "0.5.2", 266 | "merge-descriptors": "1.0.1", 267 | "methods": "1.1.2", 268 | "on-finished": "2.3.0", 269 | "parseurl": "1.3.3", 270 | "path-to-regexp": "0.1.7", 271 | "proxy-addr": "2.0.6", 272 | "qs": "6.7.0", 273 | "range-parser": "1.2.1", 274 | "safe-buffer": "5.1.2", 275 | "send": "0.17.1", 276 | "serve-static": "1.14.1", 277 | "setprototypeof": "1.1.1", 278 | "statuses": "1.5.0", 279 | "type-is": "1.6.18", 280 | "utils-merge": "1.0.1", 281 | "vary": "1.1.2" 282 | } 283 | }, 284 | "file-uri-to-path": { 285 | "version": "1.0.0", 286 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 287 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" 288 | }, 289 | "finalhandler": { 290 | "version": "1.1.2", 291 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 292 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 293 | "requires": { 294 | "debug": "2.6.9", 295 | "encodeurl": "1.0.2", 296 | "escape-html": "1.0.3", 297 | "on-finished": "2.3.0", 298 | "parseurl": "1.3.3", 299 | "statuses": "1.5.0", 300 | "unpipe": "1.0.0" 301 | } 302 | }, 303 | "forwarded": { 304 | "version": "0.1.2", 305 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 306 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 307 | }, 308 | "fresh": { 309 | "version": "0.5.2", 310 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 311 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 312 | }, 313 | "fs-constants": { 314 | "version": "1.0.0", 315 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 316 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" 317 | }, 318 | "fs-minipass": { 319 | "version": "1.2.7", 320 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", 321 | "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", 322 | "requires": { 323 | "minipass": "2.9.0" 324 | } 325 | }, 326 | "gauge": { 327 | "version": "2.7.4", 328 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 329 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 330 | "requires": { 331 | "aproba": "1.2.0", 332 | "console-control-strings": "1.1.0", 333 | "has-unicode": "2.0.1", 334 | "object-assign": "4.1.1", 335 | "signal-exit": "3.0.3", 336 | "string-width": "1.0.2", 337 | "strip-ansi": "3.0.1", 338 | "wide-align": "1.1.3" 339 | } 340 | }, 341 | "github-from-package": { 342 | "version": "0.0.0", 343 | "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", 344 | "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" 345 | }, 346 | "has-unicode": { 347 | "version": "2.0.1", 348 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 349 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" 350 | }, 351 | "http-errors": { 352 | "version": "1.7.2", 353 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 354 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 355 | "requires": { 356 | "depd": "1.1.2", 357 | "inherits": "2.0.3", 358 | "setprototypeof": "1.1.1", 359 | "statuses": "1.5.0", 360 | "toidentifier": "1.0.0" 361 | } 362 | }, 363 | "iconv-lite": { 364 | "version": "0.4.24", 365 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 366 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 367 | "requires": { 368 | "safer-buffer": "2.1.2" 369 | } 370 | }, 371 | "ieee754": { 372 | "version": "1.2.1", 373 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 374 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" 375 | }, 376 | "inherits": { 377 | "version": "2.0.3", 378 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 379 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 380 | }, 381 | "ini": { 382 | "version": "1.3.5", 383 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 384 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 385 | }, 386 | "ipaddr.js": { 387 | "version": "1.9.1", 388 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 389 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 390 | }, 391 | "is-fullwidth-code-point": { 392 | "version": "1.0.0", 393 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 394 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 395 | "requires": { 396 | "number-is-nan": "1.0.1" 397 | } 398 | }, 399 | "isarray": { 400 | "version": "1.0.0", 401 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 402 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 403 | }, 404 | "media-typer": { 405 | "version": "0.3.0", 406 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 407 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 408 | }, 409 | "merge-descriptors": { 410 | "version": "1.0.1", 411 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 412 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 413 | }, 414 | "methods": { 415 | "version": "1.1.2", 416 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 417 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 418 | }, 419 | "mime": { 420 | "version": "1.6.0", 421 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 422 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 423 | }, 424 | "mime-db": { 425 | "version": "1.44.0", 426 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", 427 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" 428 | }, 429 | "mime-types": { 430 | "version": "2.1.27", 431 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", 432 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", 433 | "requires": { 434 | "mime-db": "1.44.0" 435 | } 436 | }, 437 | "mimic-response": { 438 | "version": "2.1.0", 439 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", 440 | "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" 441 | }, 442 | "minimist": { 443 | "version": "1.2.5", 444 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 445 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" 446 | }, 447 | "minipass": { 448 | "version": "2.9.0", 449 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", 450 | "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", 451 | "requires": { 452 | "safe-buffer": "5.1.2", 453 | "yallist": "3.1.1" 454 | } 455 | }, 456 | "minizlib": { 457 | "version": "1.3.3", 458 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", 459 | "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", 460 | "requires": { 461 | "minipass": "2.9.0" 462 | } 463 | }, 464 | "mkdirp": { 465 | "version": "0.5.5", 466 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 467 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 468 | "requires": { 469 | "minimist": "1.2.5" 470 | } 471 | }, 472 | "mkdirp-classic": { 473 | "version": "0.5.3", 474 | "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 475 | "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" 476 | }, 477 | "ms": { 478 | "version": "2.0.0", 479 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 480 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 481 | }, 482 | "napi-build-utils": { 483 | "version": "1.0.2", 484 | "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", 485 | "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" 486 | }, 487 | "negotiator": { 488 | "version": "0.6.2", 489 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 490 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 491 | }, 492 | "node-abi": { 493 | "version": "2.19.3", 494 | "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.3.tgz", 495 | "integrity": "sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg==", 496 | "requires": { 497 | "semver": "5.7.1" 498 | } 499 | }, 500 | "node-fetch": { 501 | "version": "2.6.1", 502 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", 503 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" 504 | }, 505 | "nodemailer": { 506 | "version": "6.4.16", 507 | "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.16.tgz", 508 | "integrity": "sha512-68K0LgZ6hmZ7PVmwL78gzNdjpj5viqBdFqKrTtr9bZbJYj6BRj5W6WGkxXrEnUl3Co3CBXi3CZBUlpV/foGnOQ==" 509 | }, 510 | "noop-logger": { 511 | "version": "0.1.1", 512 | "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", 513 | "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" 514 | }, 515 | "npmlog": { 516 | "version": "4.1.2", 517 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 518 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 519 | "requires": { 520 | "are-we-there-yet": "1.1.5", 521 | "console-control-strings": "1.1.0", 522 | "gauge": "2.7.4", 523 | "set-blocking": "2.0.0" 524 | } 525 | }, 526 | "number-is-nan": { 527 | "version": "1.0.1", 528 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 529 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 530 | }, 531 | "object-assign": { 532 | "version": "4.1.1", 533 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 534 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 535 | }, 536 | "on-finished": { 537 | "version": "2.3.0", 538 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 539 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 540 | "requires": { 541 | "ee-first": "1.1.1" 542 | } 543 | }, 544 | "once": { 545 | "version": "1.4.0", 546 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 547 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 548 | "requires": { 549 | "wrappy": "1.0.2" 550 | } 551 | }, 552 | "parseurl": { 553 | "version": "1.3.3", 554 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 555 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 556 | }, 557 | "path-to-regexp": { 558 | "version": "0.1.7", 559 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 560 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 561 | }, 562 | "prebuild-install": { 563 | "version": "5.3.6", 564 | "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", 565 | "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", 566 | "requires": { 567 | "detect-libc": "1.0.3", 568 | "expand-template": "2.0.3", 569 | "github-from-package": "0.0.0", 570 | "minimist": "1.2.5", 571 | "mkdirp-classic": "0.5.3", 572 | "napi-build-utils": "1.0.2", 573 | "node-abi": "2.19.3", 574 | "noop-logger": "0.1.1", 575 | "npmlog": "4.1.2", 576 | "pump": "3.0.0", 577 | "rc": "1.2.8", 578 | "simple-get": "3.1.0", 579 | "tar-fs": "2.1.1", 580 | "tunnel-agent": "0.6.0", 581 | "which-pm-runs": "1.0.0" 582 | } 583 | }, 584 | "process-nextick-args": { 585 | "version": "2.0.1", 586 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 587 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 588 | }, 589 | "proxy-addr": { 590 | "version": "2.0.6", 591 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", 592 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", 593 | "requires": { 594 | "forwarded": "0.1.2", 595 | "ipaddr.js": "1.9.1" 596 | } 597 | }, 598 | "pump": { 599 | "version": "3.0.0", 600 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 601 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 602 | "requires": { 603 | "end-of-stream": "1.4.4", 604 | "once": "1.4.0" 605 | } 606 | }, 607 | "qs": { 608 | "version": "6.7.0", 609 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 610 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 611 | }, 612 | "range-parser": { 613 | "version": "1.2.1", 614 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 615 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 616 | }, 617 | "raw-body": { 618 | "version": "2.4.0", 619 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 620 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 621 | "requires": { 622 | "bytes": "3.1.0", 623 | "http-errors": "1.7.2", 624 | "iconv-lite": "0.4.24", 625 | "unpipe": "1.0.0" 626 | } 627 | }, 628 | "rc": { 629 | "version": "1.2.8", 630 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 631 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 632 | "requires": { 633 | "deep-extend": "0.6.0", 634 | "ini": "1.3.5", 635 | "minimist": "1.2.5", 636 | "strip-json-comments": "2.0.1" 637 | } 638 | }, 639 | "readable-stream": { 640 | "version": "2.3.7", 641 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 642 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 643 | "requires": { 644 | "core-util-is": "1.0.2", 645 | "inherits": "2.0.3", 646 | "isarray": "1.0.0", 647 | "process-nextick-args": "2.0.1", 648 | "safe-buffer": "5.1.2", 649 | "string_decoder": "1.1.1", 650 | "util-deprecate": "1.0.2" 651 | } 652 | }, 653 | "safe-buffer": { 654 | "version": "5.1.2", 655 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 656 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 657 | }, 658 | "safer-buffer": { 659 | "version": "2.1.2", 660 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 661 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 662 | }, 663 | "semver": { 664 | "version": "5.7.1", 665 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 666 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 667 | }, 668 | "send": { 669 | "version": "0.17.1", 670 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 671 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 672 | "requires": { 673 | "debug": "2.6.9", 674 | "depd": "1.1.2", 675 | "destroy": "1.0.4", 676 | "encodeurl": "1.0.2", 677 | "escape-html": "1.0.3", 678 | "etag": "1.8.1", 679 | "fresh": "0.5.2", 680 | "http-errors": "1.7.2", 681 | "mime": "1.6.0", 682 | "ms": "2.1.1", 683 | "on-finished": "2.3.0", 684 | "range-parser": "1.2.1", 685 | "statuses": "1.5.0" 686 | }, 687 | "dependencies": { 688 | "ms": { 689 | "version": "2.1.1", 690 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 691 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 692 | } 693 | } 694 | }, 695 | "serve-static": { 696 | "version": "1.14.1", 697 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 698 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 699 | "requires": { 700 | "encodeurl": "1.0.2", 701 | "escape-html": "1.0.3", 702 | "parseurl": "1.3.3", 703 | "send": "0.17.1" 704 | } 705 | }, 706 | "set-blocking": { 707 | "version": "2.0.0", 708 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 709 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 710 | }, 711 | "setprototypeof": { 712 | "version": "1.1.1", 713 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 714 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 715 | }, 716 | "signal-exit": { 717 | "version": "3.0.3", 718 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 719 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" 720 | }, 721 | "simple-concat": { 722 | "version": "1.0.1", 723 | "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", 724 | "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" 725 | }, 726 | "simple-get": { 727 | "version": "3.1.0", 728 | "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", 729 | "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", 730 | "requires": { 731 | "decompress-response": "4.2.1", 732 | "once": "1.4.0", 733 | "simple-concat": "1.0.1" 734 | } 735 | }, 736 | "statuses": { 737 | "version": "1.5.0", 738 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 739 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 740 | }, 741 | "string-width": { 742 | "version": "1.0.2", 743 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 744 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 745 | "requires": { 746 | "code-point-at": "1.1.0", 747 | "is-fullwidth-code-point": "1.0.0", 748 | "strip-ansi": "3.0.1" 749 | } 750 | }, 751 | "string_decoder": { 752 | "version": "1.1.1", 753 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 754 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 755 | "requires": { 756 | "safe-buffer": "5.1.2" 757 | } 758 | }, 759 | "strip-ansi": { 760 | "version": "3.0.1", 761 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 762 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 763 | "requires": { 764 | "ansi-regex": "2.1.1" 765 | } 766 | }, 767 | "strip-json-comments": { 768 | "version": "2.0.1", 769 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 770 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 771 | }, 772 | "tar": { 773 | "version": "4.4.10", 774 | "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", 775 | "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", 776 | "requires": { 777 | "chownr": "1.1.4", 778 | "fs-minipass": "1.2.7", 779 | "minipass": "2.9.0", 780 | "minizlib": "1.3.3", 781 | "mkdirp": "0.5.5", 782 | "safe-buffer": "5.1.2", 783 | "yallist": "3.1.1" 784 | } 785 | }, 786 | "tar-fs": { 787 | "version": "2.1.1", 788 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", 789 | "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", 790 | "requires": { 791 | "chownr": "1.1.4", 792 | "mkdirp-classic": "0.5.3", 793 | "pump": "3.0.0", 794 | "tar-stream": "2.1.4" 795 | } 796 | }, 797 | "tar-stream": { 798 | "version": "2.1.4", 799 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.4.tgz", 800 | "integrity": "sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw==", 801 | "requires": { 802 | "bl": "4.0.3", 803 | "end-of-stream": "1.4.4", 804 | "fs-constants": "1.0.0", 805 | "inherits": "2.0.3", 806 | "readable-stream": "3.6.0" 807 | }, 808 | "dependencies": { 809 | "readable-stream": { 810 | "version": "3.6.0", 811 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 812 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 813 | "requires": { 814 | "inherits": "2.0.3", 815 | "string_decoder": "1.1.1", 816 | "util-deprecate": "1.0.2" 817 | } 818 | } 819 | } 820 | }, 821 | "toidentifier": { 822 | "version": "1.0.0", 823 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 824 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 825 | }, 826 | "tunnel-agent": { 827 | "version": "0.6.0", 828 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 829 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 830 | "requires": { 831 | "safe-buffer": "5.1.2" 832 | } 833 | }, 834 | "type-is": { 835 | "version": "1.6.18", 836 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 837 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 838 | "requires": { 839 | "media-typer": "0.3.0", 840 | "mime-types": "2.1.27" 841 | } 842 | }, 843 | "unpipe": { 844 | "version": "1.0.0", 845 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 846 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 847 | }, 848 | "util-deprecate": { 849 | "version": "1.0.2", 850 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 851 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 852 | }, 853 | "utils-merge": { 854 | "version": "1.0.1", 855 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 856 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 857 | }, 858 | "vary": { 859 | "version": "1.1.2", 860 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 861 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 862 | }, 863 | "which-pm-runs": { 864 | "version": "1.0.0", 865 | "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", 866 | "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" 867 | }, 868 | "wide-align": { 869 | "version": "1.1.3", 870 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 871 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 872 | "requires": { 873 | "string-width": "1.0.2" 874 | } 875 | }, 876 | "wrappy": { 877 | "version": "1.0.2", 878 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 879 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 880 | }, 881 | "yallist": { 882 | "version": "3.1.1", 883 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", 884 | "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" 885 | } 886 | } 887 | } 888 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "share-domain", 3 | "version": "1.0.0", 4 | "description": "share your secondary domain", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "author": "zcmimi", 10 | "license": "ISC", 11 | "dependencies": { 12 | "better-sqlite3": "^7.1.1", 13 | "cookie-parser": "^1.4.5", 14 | "express": "^4.17.1", 15 | "node-fetch": "^2.6.1", 16 | "nodemailer": "^6.4.16" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## share-domain 2 | 3 | 分享你的二级域名! 4 | 5 | 一个自动化二级域名分发系统,基于`nodejs` 6 | 7 | 调用`cloudflare api V4` 8 | 9 | [demo](https://kksk.best) 10 | 11 | ## 食用 12 | 13 | 请先确保你的域名是用cloudflare解析的,并已经获取了cloudflare的api token 14 | 15 | 1. 克隆仓库 16 | 17 | 2. `npm install` 18 | 19 | 3. 请复制`config.default.js`到`config.js`,并自行配置 20 | 21 | 4. `node index.js` -------------------------------------------------------------------------------- /send.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | const nodemailer=require('nodemailer'); 3 | var config,transporter; 4 | // 发送邮件 5 | async function send(to,subject,html){ 6 | var info=await transporter.sendMail({from:config.from,to,subject,html}); 7 | return info; 8 | }; 9 | async function sendToken(email,token){ 10 | return await send(email,'Your token (from kksk.best)', 11 | `Your token: ${token}`,); 12 | } 13 | // (async function test(){ 14 | // config=require("./config").mailer; 15 | // transporter=nodemailer.createTransport(config.mailer); 16 | // console.log(await sendToken('zcmimiksp@gmail.com','fdasfasg')); 17 | // })(); 18 | module.exports=(conf)=>{ 19 | config=conf; 20 | transporter=nodemailer.createTransport(config.mailer); 21 | return {sendToken} 22 | }; -------------------------------------------------------------------------------- /static/css/style.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin: 0; 3 | background: #f7a4b91a; 4 | } 5 | .container{ 6 | width: 92%; 7 | max-width: 1280px; 8 | margin-left: auto; 9 | margin-right: auto; 10 | } 11 | *{ 12 | font-size: 32px; 13 | color:#f79cb3; 14 | } 15 | input,select{ 16 | outline-style: none; 17 | color: #f76d8f; 18 | border: 1px dashed #f7b9ca; 19 | border-radius: 5px; 20 | padding: 10px 10px; 21 | } 22 | input:focus,select:focus{ 23 | border: solid #f7a4b9 2px; 24 | /* outline: 0; */ 25 | } 26 | ::-webkit-input-placeholder{color: #f9c6cf;} 27 | :-moz-placeholder{color: #f9c6cf;}/* Firefox 18- */ 28 | ::-moz-placeholder{color: #f9c6cf;}/* Firefox 19+ */ 29 | :-ms-input-placeholder{color: #f9c6cf;} 30 | button{ 31 | border: none; 32 | border-radius: 5px; 33 | padding: 10px 10px; 34 | background-color: #ffffff;color:#f7a4b9; 35 | outline-style: none; 36 | box-shadow: 2px 3px 7px 2px rgba(0,0,0,.02); 37 | margin:5px; 38 | } 39 | button:hover{ 40 | border: 2px solid #f7a4b9; 41 | /* background-color: #f7a4b9;color: #fff; */ 42 | cursor: pointer; 43 | transition:200ms; 44 | box-shadow: none; 45 | } 46 | button:active{ 47 | background-color: #f7a4b9;color: #fff; 48 | transition:500ms; 49 | } 50 | ::selection{ 51 | background: #f7a4b9; 52 | color:#fff; 53 | } 54 | 55 | table input{ 56 | max-width: 150px; 57 | } 58 | table th,table button{margin: 5px;} 59 | 60 | #notice{ 61 | position: fixed;top: 0;left:0;right:0;margin: auto; 62 | padding: 7px; 63 | border: 5px solid #f8c6d2; 64 | border-top: none; 65 | background: #f7a4b9;color: #fff; 66 | /* border-radius: 5px; */ 67 | border-bottom-left-radius: 5px; 68 | border-bottom-right-radius: 5px; 69 | width: fit-content; 70 | } 71 | #loading{ 72 | position: fixed;top: 0;right: 0;margin: 1%; 73 | width: 40px;height: 40px; 74 | border-radius: 50%; 75 | background-color: #fff; 76 | } 77 | #loading div{ 78 | box-sizing: border-box; 79 | position: absolute; 80 | width: 100%; 81 | height: 100%; 82 | /* margin: 8px; */ 83 | border: 3px solid #f7a4b9; 84 | border-radius: 50%; 85 | animation: loading 1.2s cubic-bezier(0.5,0,0.5,1) infinite; 86 | border-color: #f7a4b9 transparent transparent transparent; 87 | box-shadow: 2px 3px 7px 2px rgba(0,0,0,.02); 88 | } 89 | #loading div:nth-child(1){animation-delay:-0.45s;} 90 | #loading div:nth-child(2){animation-delay: -0.3s;} 91 | #loading div:nth-child(3){animation-delay: -0.15s;} 92 | @keyframes loading{ 93 | 0%{transform: rotate(0deg);} 94 | 100%{transform: rotate(360deg);} 95 | } 96 | a[target="_blank"]::after{ 97 | content: url('/svg/link.svg'); 98 | border-radius: 5px; 99 | padding: 5px 5px; 100 | background-color: #ffffff; 101 | box-shadow: 2px 3px 7px 2px rgba(0,0,0,.02); 102 | /* margin: 0 3px 0 5px; */ 103 | } 104 | a[target="_blank"]:hover::after{ 105 | border: 2px solid #f7a4b9; 106 | cursor: pointer; 107 | transition:200ms; 108 | box-shadow: none; 109 | } 110 | #star{ 111 | font-size: 20px; 112 | position:fixed; 113 | bottom:0;left:0; 114 | margin:1%; 115 | } -------------------------------------------------------------------------------- /static/css/style.min.css: -------------------------------------------------------------------------------- 1 | body{margin:0;background:#f7a4b91a}.container{width:92%;max-width:1280px;margin-left:auto;margin-right:auto}*{font-size:32px;color:#f79cb3}input,select{outline-style:none;color:#f76d8f;border:1px dashed #f7b9ca;border-radius:5px;padding:10px 10px}input:focus,select:focus{border:solid #f7a4b9 2px}::-webkit-input-placeholder{color:#f9c6cf}:-moz-placeholder{color:#f9c6cf}::-moz-placeholder{color:#f9c6cf}:-ms-input-placeholder{color:#f9c6cf}button{border:none;border-radius:5px;padding:10px 10px;background-color:#fff;color:#f7a4b9;outline-style:none;box-shadow:2px 3px 7px 2px rgba(0,0,0,.02);margin:5px}button:hover{border:2px solid #f7a4b9;cursor:pointer;transition:.2s;box-shadow:none}button:active{background-color:#f7a4b9;color:#fff;transition:.5s}::selection{background:#f7a4b9;color:#fff}table input{max-width:150px}table button,table th{margin:5px}#notice{position:fixed;top:0;left:0;right:0;margin:auto;padding:7px;border:5px solid #f8c6d2;border-top:none;background:#f7a4b9;color:#fff;border-bottom-left-radius:5px;border-bottom-right-radius:5px;width:fit-content}#loading{position:fixed;top:0;right:0;margin:1%;width:40px;height:40px;border-radius:50%;background-color:#fff}#loading div{box-sizing:border-box;position:absolute;width:100%;height:100%;border:3px solid #f7a4b9;border-radius:50%;animation:loading 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:#f7a4b9 transparent transparent transparent;box-shadow:2px 3px 7px 2px rgba(0,0,0,.02)}#loading div:nth-child(1){animation-delay:-.45s}#loading div:nth-child(2){animation-delay:-.3s}#loading div:nth-child(3){animation-delay:-.15s}@keyframes loading{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}a[target="_blank"]::after{content:url(/svg/link.svg);border-radius:5px;padding:5px 5px;background-color:#fff;box-shadow:2px 3px 7px 2px rgba(0,0,0,.02)}a[target="_blank"]:hover::after{border:2px solid #f7a4b9;cursor:pointer;transition:.2s;box-shadow:none}#star{font-size:20px;position:fixed;bottom:0;left:0;margin:1%} -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 |
16 |
17 |

18 | 19 | 20 | 21 |

22 |

23 | 24 | 25 |

26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 41 | 48 | 51 | 65 | 68 | 69 | 70 | 71 | 72 | 73 |
NameTypeContentTTLAction
39 | 40 | 42 | 47 | 49 | 50 | 52 | 64 | 66 | 67 |
74 |
75 | 76 | 79 | 80 | -------------------------------------------------------------------------------- /static/js/bundle.js: -------------------------------------------------------------------------------- 1 | function E(id){return document.getElementById(id);} 2 | function V(id){return E(id).value.trim();} 3 | function startLoading(){E('loading').hidden=0;} 4 | function stopLoading(){E('loading').hidden=1;} 5 | function sleep(ti){return new Promise((resolve)=>setTimeout(resolve,ti));} 6 | function Notice(s,ti=2000){ 7 | var notice=E('notice'); 8 | notice.innerText=s;notice.style.opacity=1;noticefade=0;function fade(){if(noticefade)if((notice.style.opacity-=0.01)>0) 9 | requestAnimationFrame(fade);} 10 | sleep(ti).then(()=>{noticefade=1;fade();}); 11 | } 12 | async function post(url,body,showLoading=1){ 13 | if(showLoading)startLoading(); 14 | var res=await fetch(url,{ 15 | method: "POST", 16 | body:JSON.stringify(body), 17 | headers: {'content-type': 'application/json'}, 18 | }).then(res=>res.json()); 19 | if(showLoading)stopLoading(); 20 | return res; 21 | } 22 | async function sendToken(re=0){ 23 | var email=V('email'); 24 | var res=await post('/api/sendToken',{email,re}); 25 | Notice(res.data); 26 | } 27 | async function Fetch(log=1){ 28 | var token=V('token'),email=V('email'); 29 | var res=await post('/api/chkToken',{email,token}); 30 | if(!res.status)Notice(res.data.error),E('token').Vue=''; 31 | else{ 32 | if(log)Notice(res.data); 33 | showAll(); 34 | } 35 | } 36 | async function add(){ 37 | var name=V('name')+'.'+zone_name,type=V('type'),content=V('content'),ttl=Number(V('ttl')); 38 | var res=await post('/api/add',{ 39 | email:V('email'),token:V('token'), 40 | record:{type,name,content,ttl} 41 | }); 42 | console.log(res.data); 43 | if(res.status) 44 | Notice(`success id:${res.data.result.id}`),sleep(1000).then(()=>{ 45 | Fetch(0); 46 | E('name').value='';E('content').value=''; 47 | }); 48 | else Notice(`failed: ${res.data.error}`); 49 | } 50 | async function all(){ 51 | var res=await post('/api/all',{ 52 | email:V('email'),token:V('token') 53 | }); 54 | return res.data; 55 | } 56 | function CE(tag){return document.createElement(tag);} 57 | async function showAll(){ 58 | var res=await all(),l=E('items'); 59 | l.innerHTML=''; 60 | function Input(val){ 61 | var x=CE('input');x.value=val; 62 | return x; 63 | } 64 | function Typeselect(type){ 65 | var x=CE('select'),list=['A','CNAME']; 66 | for(var i of list){ 67 | var y=CE('option');y.innerText=i;y.value=i; 68 | if(type==i)y.selected='selected'; 69 | x.append(y); 70 | } 71 | return x; 72 | } 73 | function TTLselect(ttl){ 74 | var x=CE('select'),cTTL={ 75 | 1:'AUTO',2:'2',5:'5',10:'10',15:'15', 76 | 60:'1H',120:'2H',300:'5H',720:'12H',1440:'1D' 77 | }; 78 | for(var i in cTTL){ 79 | var y=CE('option'); 80 | y.value=i;y.innerText=cTTL[i]; 81 | if(ttl==i)y.selected='selected'; 82 | x.append(y); 83 | } 84 | return x; 85 | } 86 | for(var i of res){ 87 | var item=CE('tr'), 88 | name=CE('th'),type=CE('th'),content=CE('th'),ttl=CE('th'),action=CE('th'); 89 | name.append(Input(i.name.slice(0,i.name.length-zone_name.length-1)));name.align='left'; 90 | type.append(Typeselect(i.type));type.align='left'; 91 | content.append(Input(i.content));content.align='left'; 92 | ttl.append(TTLselect(i.ttl));ttl.align='left'; 93 | var Del=CE('button'),Edit=CE('button'),visit=CE('a'); 94 | Del.innerText='Del'; 95 | Del.onclick=(x)=>{del(x.target.parentElement.parentElement.id);} 96 | Edit.innerText='Edit'; 97 | Edit.onclick=(x)=>{edit(x.target.parentElement.parentElement.id);} 98 | visit.href='http://'+i.name;visit.target='_blank'; 99 | // visit.innerText='visit'; 100 | action.append(Del,Edit,visit); 101 | item.id=i.id; 102 | item.append(name,type,content,ttl,action); 103 | l.append(item); 104 | } 105 | } 106 | async function del(id){ 107 | var res=await post('/api/del',{ 108 | email:V('email'),token:V('token'), 109 | record:{id} 110 | }); 111 | console.log(res.data); 112 | if(res.status)Notice(`success id:${res.data.result.id}`),sleep(1000).then(()=>{ 113 | Fetch(0); 114 | }); 115 | else Notice(`failed: ${res.data.error}`); 116 | } 117 | async function edit(id){ 118 | var item=E(id); 119 | var name=item.children[0].children[0].value+'.'+zone_name, 120 | type=item.children[1].children[0].value, 121 | content=item.children[2].children[0].value, 122 | ttl=item.children[3].children[0].value; 123 | var res=await post('/api/edit',{ 124 | email:V('email'),token:V('token'), 125 | record:{id,type,name,content,ttl} 126 | }); 127 | console.log(res.data); 128 | if(res.status)Notice(`success id:${res.data.result.id}`),sleep(1000).then(()=>{ 129 | Fetch(0); 130 | E('name').value='';E('content').value=''; 131 | }); 132 | else Notice(`failed: ${res.data.error}`); 133 | } -------------------------------------------------------------------------------- /static/js/bundle.min.js: -------------------------------------------------------------------------------- 1 | function E(e){return document.getElementById(e)}function V(e){return E(e).value.trim()}function startLoading(){E("loading").hidden=0}function stopLoading(){E("loading").hidden=1}function sleep(e){return new Promise(t=>setTimeout(t,e))}function Notice(e,t=2e3){function n(){noticefade&&(a.style.opacity-=.01)>0&&requestAnimationFrame(n)}var a=E("notice");a.innerText=e,a.style.opacity=1,noticefade=0,sleep(t).then(()=>{noticefade=1,n()})}async function post(e,t,n=1){n&&startLoading();var a=await fetch(e,{method:"POST",body:JSON.stringify(t),headers:{"content-type":"application/json"}}).then(e=>e.json());return n&&stopLoading(),a}async function sendToken(e=0){var t=V("email"),n=await post("/api/sendToken",{email:t,re:e});Notice(n.data)}async function Fetch(e=1){var t=V("token"),n=V("email"),a=await post("/api/chkToken",{email:n,token:t});a.status?(e&&Notice(a.data),showAll()):(Notice(a.data.error),E("token").Vue="")}async function add(){var e=V("name")+"."+zone_name,t=V("type"),n=V("content"),a=Number(V("ttl")),i=await post("/api/add",{email:V("email"),token:V("token"),record:{type:t,name:e,content:n,ttl:a}});console.log(i.data),i.status?(Notice(`success id:${i.data.result.id}`),sleep(1e3).then(()=>{Fetch(0),E("name").value="",E("content").value=""})):Notice(`failed: ${i.data.error}`)}async function all(){var e=await post("/api/all",{email:V("email"),token:V("token")});return e.data}function CE(e){return document.createElement(e)}async function showAll(){function e(e){var t=CE("input");return t.value=e,t}function t(e){var t=CE("select"),n=["A","CNAME"];for(var a of n){var i=CE("option");i.innerText=a,i.value=a,e==a&&(i.selected="selected"),t.append(i)}return t}function n(e){var t=CE("select"),n={1:"AUTO",2:"2",5:"5",10:"10",15:"15",60:"1H",120:"2H",300:"5H",720:"12H",1440:"1D"};for(var a in n){var i=CE("option");i.value=a,i.innerText=n[a],e==a&&(i.selected="selected"),t.append(i)}return t}var a=await all(),i=E("items");for(var o of(i.innerHTML="",a)){var l=CE("tr"),r=CE("th"),c=CE("th"),d=CE("th"),s=CE("th"),u=CE("th");r.append(e(o.name.slice(0,o.name.length-zone_name.length-1))),r.align="left",c.append(t(o.type)),c.align="left",d.append(e(o.content)),d.align="left",s.append(n(o.ttl)),s.align="left";var p=CE("button"),m=CE("button"),f=CE("a");p.innerText="Del",p.onclick=(e=>{del(e.target.parentElement.parentElement.id)}),m.innerText="Edit",m.onclick=(e=>{edit(e.target.parentElement.parentElement.id)}),f.href="http://"+o.name,f.target="_blank",u.append(p,m,f),l.id=o.id,l.append(r,c,d,s,u),i.append(l)}}async function del(e){var t=await post("/api/del",{email:V("email"),token:V("token"),record:{id:e}});console.log(t.data),t.status?(Notice(`success id:${t.data.result.id}`),sleep(1e3).then(()=>{Fetch(0)})):Notice(`failed: ${t.data.error}`)}async function edit(e){var t=E(e),n=t.children[0].children[0].value+"."+zone_name,a=t.children[1].children[0].value,i=t.children[2].children[0].value,o=t.children[3].children[0].value,l=await post("/api/edit",{email:V("email"),token:V("token"),record:{id:e,type:a,name:n,content:i,ttl:o}});console.log(l.data),l.status?(Notice(`success id:${l.data.result.id}`),sleep(1e3).then(()=>{Fetch(0),E("name").value="",E("content").value=""})):Notice(`failed: ${l.data.error}`)} -------------------------------------------------------------------------------- /static/svg/link.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------