@andrewcaires/api 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +2 -2
- package/dist/index.umd.js +2 -2
- package/package.json +11 -11
package/dist/index.d.ts
CHANGED
package/dist/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/api v1.0.
|
|
2
|
+
* @andrewcaires/api v1.0.7
|
|
3
3
|
* Simple api for small applications using express, jsonwebtoken, sequelize and websocket
|
|
4
4
|
* (c) 2022 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
6
6
|
*/
|
|
7
|
-
import{toBool as e,dateFormat as t,isArray as r,isString as o,noop as s,sleep as i,uniqueID as n,allowedObject as a,uuidv4 as d}from"@andrewcaires/utils.js";import{config as u}from"dotenv";import{UUID as c,UUIDV4 as l,Sequelize as m,DataTypes as p,Model as v,Op as g}from"sequelize";import*as f from"http";import*as h from"https";import{Server as y}from"net";import w from"cors";import I,{Router as b}from"express";import{existsSync as S,readFileSync as T}from"fs";import{SHA256 as A}from"crypto-js";import{sign as N,verify as O}from"jsonwebtoken";import E from"mime-types";import _ from"multer";import{join as P}from"path";import R from"joi";import q from"ws";function j(e,t,r,o){return new(r||(r=Promise))((function(s,i){function n(e){try{d(o.next(e))}catch(e){i(e)}}function a(e){try{d(o.throw(e))}catch(e){i(e)}}function d(e){var t;e.done?s(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,a)}d((o=o.apply(e,t||[])).next())}))}u();const k=parseInt(process.env.API_AUTH_SLEEP||"1000"),x=process.env.API_DB_DATABASE||"",D=process.env.API_DB_HOST||"127.0.0.1",B=process.env.API_DB_PASSWORD||"",G=parseInt(process.env.API_DB_PORT||"3306"),z=process.env.API_DB_TYPE||"",U=process.env.API_DB_USERNAME||"root",C=e(process.env.API_DB_LOG||"false"),L=process.env.API_HTTP_CRT||"",H=process.env.API_HTTP_KEY||"",K=parseInt(process.env.API_HTTP_PORT||"3000"),M=process.env.API_HTTP_PUBLIC||"",F=e(process.env.API_HTTP_CROSS||"false"),W=e(process.env.API_HTTP_HYBRID||"false"),X=process.env.API_TOKEN_CRT||"",Y=process.env.API_TOKEN_KEY||"",J=process.env.API_TOKEN_HEADER||"authorization",V=parseInt(process.env.API_TOKEN_LIFETIME||"15"),$=parseInt(process.env.API_UPLOAD_COUNT||"1"),Z=process.env.API_UPLOAD_FIELD||"upload",Q=parseInt(process.env.API_UPLOAD_SIZE||"2"),ee=process.env.API_UPLOAD_TEMP||"./temp",te=e(process.env.API_WEBSOCKET_START||"false"),re={type:c,defaultValue:l,allowNull:!1,primaryKey:!0},oe=(()=>{switch(z){case"mariadb":return new m(x,U,B,{host:D,port:G,dialect:"mariadb",logging:C,define:{timestamps:!1}});case"mysql":return new m(x,U,B,{host:D,port:G,dialect:"mysql",logging:C,define:{timestamps:!1}});case"postgres":return new m(x,U,B,{host:D,port:G,dialect:"postgres",logging:C,define:{timestamps:!1}})}throw new Error("No database selected")})();class se extends v{}se.init({login:p.BIGINT,logout:p.BIGINT,secret:p.STRING,timestamp:p.BIGINT,useragent:p.STRING},{sequelize:oe,modelName:"auth"});class ie extends v{}ie.init({name:p.STRING,description:p.TEXT,state:p.BOOLEAN},{sequelize:oe,modelName:"group"});class ne extends v{}ne.init({name:p.STRING,description:p.TEXT,state:p.BOOLEAN},{sequelize:oe,modelName:"route"});class ae extends v{}ae.init({},{sequelize:oe,modelName:"groups_routes"}),ae.removeAttribute("id");class de extends v{}de.init({name:p.STRING,email:p.STRING,username:p.STRING,password:p.STRING,description:p.TEXT,state:p.BOOLEAN},{sequelize:oe,modelName:"user"});class ue extends v{}ue.init({},{sequelize:oe,modelName:"users_groups"}),ue.removeAttribute("id");class ce extends v{}ce.init({key:p.STRING,value:p.STRING},{sequelize:oe,modelName:"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),ce.removeAttribute("id");class le extends v{}var me;le.init({type:p.STRING,source:p.STRING,message:p.TEXT},{sequelize:oe,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),de.hasMany(se),se.belongsTo(de),ie.hasMany(ae),ae.belongsTo(ie),ne.hasMany(ae),ae.belongsTo(ne),de.hasMany(ue),ue.belongsTo(de),ie.hasMany(ue),ue.belongsTo(ie),function(e){e.ERROR="[31m",e.INFO="[36m",e.NONE="[37m",e.SUCCESS="[32m",e.WARNING="[33m"}(me||(me={}));class pe{static write(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.NONE,"",e,t,r)}))}static error(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.ERROR,"error",e,t,r)}))}static info(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.INFO,"info",e,t,r)}))}static success(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.ERROR,"success",e,t,r)}))}static warning(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.WARNING,"warning",e,t,r)}))}static writeConsole(e,r,o){const s=t(new Date,"%H:%M:%S");console.log(">",e,r+" ".repeat(10-r.length),"[37m","|",s,"|",o)}static writeRaw(e,t,r,o,s){return j(this,void 0,void 0,(function*(){s&&pe.writeConsole(e,t,r),yield le.create({type:t,source:o,message:r}).catch((()=>null))}))}}class ve{static all(){return j(this,void 0,void 0,(function*(){const e=yield ce.findAll().catch((e=>{pe.error(e.message,"api.config",!0)})),t={};return e&&e.forEach((e=>{t[e.key]=e.value})),t}))}static del(e){return j(this,void 0,void 0,(function*(){return((yield ce.destroy({where:{key:e}}).catch((e=>{pe.error(e.message,"api.config",!0)})))||0)>0}))}static get(e){return j(this,void 0,void 0,(function*(){const t=yield ce.findOne({where:{key:e}}).catch((e=>{pe.error(e.message,"api.config",!0)}));return t&&t.value||""}))}static set(e,t){return j(this,void 0,void 0,(function*(){const[r]=(yield ce.findOrCreate({where:{key:e}}).catch((e=>{pe.error(e.message,"api.config",!0)})))||[];r&&(r.value=t,yield r.save().catch((e=>{pe.error(e.message,"api.config",!0)})))}))}}class ge{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t,r){return e.status(400).json({message:t,details:r})}static unauthorized(e,t){return e.status(401).json({message:t})}}class fe{constructor(e){this.model=e}add(){return(e,t)=>j(this,void 0,void 0,(function*(){const r=yield this.model.create(e.body).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)}));return r?ge.data(t,{id:r.id}):ge.error(t,"Internal Server Error")}))}all(e,t){return(i,n)=>j(this,void 0,void 0,(function*(){var a,d,u,c,l;const m=Object.assign({},e||{});m.where=Object.assign({},m.where||{});const p=null===(a=i.query.limit)||void 0===a?void 0:a.toString();p&&(m.limit=parseInt(p));const v=null===(d=i.query.offset)||void 0===d?void 0:d.toString();v&&(m.offset=parseInt(v));const f=Object.keys(this.model.getAttributes()),h=[],y=null===(u=i.query.asc)||void 0===u?void 0:u.toString();y&&y.length&&y.split(",").forEach((e=>{f.indexOf(e)>=0&&h.push([e,"ASC"])}));const w=null===(c=i.query.desc)||void 0===c?void 0:c.toString();w&&w.length&&w.split(",").forEach((e=>{f.indexOf(e)>=0&&h.push([e,"DESC"])})),h.length&&(m.order=h);const I=[],b=r(m.attributes)?m.attributes:f,S=null===(l=i.query.search)||void 0===l?void 0:l.toString();b.forEach((e=>{var t;if(o(e)&&(S&&S.length&&I.push({[e]:{[g.like]:`%${S}%`}}),"search_"+e in i.query)){const r=null===(t=i.query["search_"+e])||void 0===t?void 0:t.toString();r&&r.length&&I.push({[e]:{[g.like]:`%${r}%`}})}})),I.length&&(m.where=Object.assign(Object.assign({},m.where),{[g.or]:[...I]}));const T=yield this.model.findAll(m).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)})),A=yield this.model.count(m).catch(s);return T?ge.data(n,{count:A,records:t?t(T):T}):ge.error(n,"Internal Server Error")}))}del(){return(e,t)=>j(this,void 0,void 0,(function*(){const{id:r}=e.params;return(yield this.model.destroy({where:{id:r}}).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)})))?ge.success(t,"OK"):ge.notfound(t,"Record not found")}))}get(e,t){return(r,o)=>j(this,void 0,void 0,(function*(){e||(e={});const s=Object.assign({},e);s.where=s.where?Object.assign({},s.where):{};const{id:i}=r.params,n=yield this.model.findByPk(i,s).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)}));return n?ge.data(o,t?t(n):n.toJSON()):null===n?ge.notfound(o,"Record not found"):ge.error(o,"Internal Server Error")}))}set(){return(e,t)=>j(this,void 0,void 0,(function*(){const{id:r}=e.params,[o]=(yield this.model.update(e.body,{where:{id:r}}).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)})))||[];return o?ge.success(t,"OK"):ge.success(t,"Record not changed")}))}}class he{static all(e,t){return j(this,void 0,void 0,(function*(){return yield ne.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:ae,required:!0,include:[{model:ie,required:!0,where:{state:!0},include:[{model:ue,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{pe.error(e.message,"api.permission",!0)}))}))}static get(e){return j(this,void 0,void 0,(function*(){const t=yield he.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return j(this,void 0,void 0,(function*(){const r=yield he.all(e,{name:t});return r&&!!r.length}))}}const ye=e=>{if(S(e))return T(e)},we={http:ye(L),token:ye(X)},Ie={http:ye(H),token:ye(Y)};class be{static sign(e){return Ie.token?{token:N(e,Ie.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static verify(e){if(!we.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:O(e,we.token)}}catch(e){return{error:"Invalid Token"}}}}const Se=["id","name","email","username"],Te=(e,t,r)=>j(void 0,void 0,void 0,(function*(){const o=e.get(J)||"",{error:s,decode:i}=be.verify(o);if(s)return ge.error(t,s);if(i){const{id:o,secret:s}=i;if(o&&i){const i=yield de.findOne({where:{id:o,state:!0}}).catch((e=>{pe.error(e.message,"api.auth",!0)}));if(i){const o=yield se.findOne({where:{secret:s,userId:i.id}}).catch((e=>{pe.error(e.message,"api.auth",!0)}));if(o){const s=Date.now();if(s>o.timestamp)return ge.error(t,"Expired token");if(!o.logout){o.timestamp=s+6e4*V;const t=e.get("User-Agent");return t&&(o.useragent=t),yield o.save(),e.auth=o,e.user=i,r()}}}return ge.error(t,"Access denied")}}return ge.error(t,"Invalid token")})),Ae=e=>(t,r,o)=>j(void 0,void 0,void 0,(function*(){const s=t.user;return s?(yield he.is(s,e))?o():ge.error(r,"Unauthorized access"):ge.unauthorized(r,"Access denied")})),Ne=(e,t)=>{const r=d()+"."+t;return S(P(e,r))?Ne(e,t):r},Oe=e=>{const t=(null==e?void 0:e.path)||ee,r=_.diskStorage({destination:(e,r,o)=>o(null,t),filename:(e,r,o)=>j(void 0,void 0,void 0,(function*(){return o(null,Ne(t,E.extension(r.mimetype)||"bin"))}))}),o=1e6*((null==e?void 0:e.size)||Q),s=_({storage:r,fileFilter(t,r,o){var s;return j(this,void 0,void 0,(function*(){const t=null===(s=null==e?void 0:e.types)||void 0===s?void 0:s.indexOf(r.mimetype);return void 0!==t&&t<0?o(new Error("File type not allowed")):o(null,!0)}))},limits:{fileSize:o}}),i=(null==e?void 0:e.count)||$,n=(null==e?void 0:e.field)||Z,a=s.array(n,i);return(e,t,r)=>{a(e,t,(function(e){return e?ge.error(t,e.message):r()}))}},Ee=e=>{const t={abortEarly:!1,allowUnknown:!0,stripUnknown:!0};return(r,o,s)=>{const{error:i,value:n}=e.validate(r.body,t);if(i){const e=i.details.map((e=>e.message)).join(", "),t=[];return i.details.forEach((e=>{var r;t.push({key:(null===(r=e.context)||void 0===r?void 0:r.key)||"",type:e.type})})),ge.validation(o,"Validation error: "+e,t)}return r.body=n,s()}},_e={username:R.string().min(5).required(),password:R.string().min(5).required()},Pe=Ee(R.object(_e)),Re=b();Re.get("/",Te,((e,t)=>j(void 0,void 0,void 0,(function*(){const r=e.user;if(!r)return ge.unauthorized(t,"Access denied");const o=yield he.all(r);if(o){const e=a(Se,r.toJSON()),s=o.map((e=>e.name));return ge.data(t,Object.assign(Object.assign({},e),{permissions:s}))}return ge.error(t,"Internal Server Error")})))),Re.post("/login",Pe,((e,t)=>j(void 0,void 0,void 0,(function*(){const{username:r,password:o}=e.body;if(!r||!o)return ge.error(t,"Invalid parameters");yield i(k);const s=yield de.findOne({where:{username:r}}).catch((e=>{pe.error(e.message,"api.controller."+de.tableName,!0)}));if(!s)return ge.notfound(t,"Username not found");if(!s.state)return ge.error(t,"Username is disabled");const a=A(o).toString();if(s.password!=a)return ge.error(t,"Invalid password");const d=s.id,u=n(),{error:c,token:l}=be.sign({id:d,secret:u});if(c)return ge.error(t,c);if(l){const r=Date.now(),o=r+6e4*V,s=e.get("User-Agent"),i=yield se.create({login:r,secret:u,timestamp:o,useragent:s,userId:d}).catch((e=>{pe.error(e.message,"api.controller."+se.tableName,!0)}));if(i)return ge.data(t,{token:l})}return ge.error(t,"Internal Server Error")})))),Re.get("/logout",Te,((e,t)=>j(void 0,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),ge.success(t,"Disconcerted")):ge.unauthorized(t,"Access denied")}))));const qe=new fe(ie),je=new fe(ae),ke=qe.add(),xe=qe.all(),De=qe.del(),Be=qe.get(),Ge=qe.set(),ze={name:R.string().min(3).required(),description:R.string().allow(null,""),state:R.boolean().required()},Ue=Ee(R.object(ze)),Ce={routes:R.array().items(R.number())},Le=Ee(R.object(Ce)),He={name:R.string().min(3).empty(""),description:R.string().allow(null,""),state:R.boolean().empty("")},Ke=Ee(R.object(He)),Me=b();Me.use(Te),Me.get("/",Ae("groups.read"),xe),Me.post("/",Ae("groups.write"),Ue,ke),Me.route("/:id").get(Ae("groups.read"),Be).put(Ae("groups.write"),Ke,Ge).delete(Ae("groups.write"),De),Me.route("/:id/routes").get(Ae("groups.read"),Le,((e,t)=>j(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return je.all({where:{groupId:r},include:[{model:ne,required:!0}]},(e=>e.map((e=>e.route))))(e,t)})))).put(Ae("groups.write"),Le,((e,t)=>j(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{routes:o}=e.body,s=yield ie.findByPk(r,{attributes:["id"]}).catch((e=>{pe.error(e.message,"api.controller."+ie.tableName,!0)}));if(s){const e=s.id;if(yield ae.destroy({where:{groupId:e}}),o){let t=0;for(let r=0;r<o.length;r++)t=yield ne.count({where:{id:o[r]}}),t&&(yield ae.create({groupId:e,routeId:o[r]}))}return ge.success(t,"OK")}return null===s?ge.notfound(t,"Record not found"):ge.error(t,"Internal Server Error")}))));const Fe=new fe(le),We=b();We.use(Te),We.get("/",Ae("logs.read"),((e,t)=>j(void 0,void 0,void 0,(function*(){const{source:r,type:o}=e.query,s=r&&o?{source:r,type:o}:r?{source:r}:o?{type:o}:{};return Fe.all({where:s,order:[["created","DESC"]]})(e,t)}))));const Xe=new fe(ne),Ye=Xe.add(),Je=Xe.all(),Ve=Xe.del(),$e=Xe.get(),Ze=Xe.set(),Qe={name:R.string().min(5).required(),description:R.string().allow(null,""),state:R.boolean().required()},et=Ee(R.object(Qe)),tt={name:R.string().min(5).empty(""),description:R.string().allow(null,""),state:R.boolean().empty("")},rt=Ee(R.object(tt)),ot=b();ot.use(Te),ot.get("/",Ae("routes.read"),Je),ot.post("/",Ae("routes.write"),et,Ye),ot.route("/:id").get(Ae("routes.read"),$e).put(Ae("routes.write"),rt,Ze).delete(Ae("routes.write"),Ve);const st=new fe(de),it=new fe(ue),nt=["id","name","email","username","description","state"],at=st.del(),dt={name:R.string().min(5).required(),email:R.string().email().required(),username:R.string().min(5).required(),password:R.string().min(5).required(),description:R.string().allow(null,""),state:R.boolean().required()},ut=Ee(R.object(dt)),ct={groups:R.array().items(R.number())},lt=Ee(R.object(ct)),mt={name:R.string().min(5).empty(""),email:R.string().email().empty(""),username:R.string().min(5).empty(""),password:R.string().min(5).empty(""),description:R.string().allow(null,""),state:R.boolean().empty("")},pt=Ee(R.object(mt)),vt=b();vt.use(Te),vt.get("/",Ae("users.read"),((e,t)=>j(void 0,void 0,void 0,(function*(){return st.all({attributes:nt})(e,t)})))),vt.post("/",Ae("users.write"),ut,((e,t)=>j(void 0,void 0,void 0,(function*(){return e.body.password=A(e.body.password).toString(),yield st.add()(e,t)})))),vt.route("/:id").get(Ae("users.read"),((e,t)=>j(void 0,void 0,void 0,(function*(){return st.get({attributes:nt})(e,t)})))).put(Ae("users.write"),pt,((e,t)=>j(void 0,void 0,void 0,(function*(){return e.body.password&&(e.body.password=A(e.body.password).toString()),st.set()(e,t)})))).delete(Ae("users.write"),at),vt.route("/:id/groups").get(Ae("users.read"),((e,t)=>j(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return it.all({where:{userId:r},include:[{model:ie,required:!0}]},(e=>e.map((e=>e.group))))(e,t)})))).put(Ae("users.write"),lt,((e,t)=>j(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{groups:o}=e.body,s=yield de.findByPk(r,{attributes:["id"]}).catch((e=>{pe.error(e.message,"api.controller."+de.tableName,!0)}));if(s){if(yield ue.destroy({where:{userId:s.id}}),o){let e=0;for(let t=0;t<o.length;t++)e=yield ie.count({where:{id:o[t]}}),e&&(yield ue.create({userId:s.id,groupId:o[t]}))}return ge.success(t,"OK")}return ge.notfound(t,"Record not found")}))));const gt=b();let ft;gt.use("/auth",Re),gt.use("/groups",Me),gt.use("/logs",We),gt.use("/routes",ot),gt.use("/users",vt);const ht=b(),yt=()=>{var e;return ft||(ft=I(),(e=ft).use(I.json()),e.use(((e,t,r,o)=>e?(pe.error(e.message,"api.express",!0),ge.error(r,"Internal Server Error")):o())),e.use(I.urlencoded({extended:!0})),e.disable("x-powered-by"),F&&e.use(w()),e.use("/api",ht),e.use("/api",gt),e.all("/api/*",((e,t)=>ge.notfound(t,"Invalid API"))),M&&(S(M)&&e.use(I.static(M)),e.get("*",((e,t)=>{if(!S(M))return ge.notfound(t,'File "index.html" not found');t.sendFile(M+"/index.html")})))),ft};let wt;const It=()=>(wt||(wt=(e=>{if(!we.http||!Ie.http){const t=f.createServer(e);return t.listen(K,(()=>pe.info("Server started on port "+K,"api.server",!0))),t}const t=f.createServer(((e,t)=>{const r=80==K?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),r=h.createServer({key:Ie.http,cert:we.http},e);if(W)return new y((e=>{e.once("data",(o=>{e.pause(),e.unshift(o),(22===o[0]?r:t).emit("connection",e),process.nextTick((()=>e.resume()))}))})).listen(K,(()=>pe.info("Server started on port "+K,"api.server",!0))),r;return 443==K&&t.listen(80,(()=>pe.info("Server started on port 80","api.server",!0))),r.listen(K,(()=>pe.info("Server started on port "+K,"api.server",!0))),r})(yt())),wt),bt=e=>{const t=new q.Server({server:e,verifyClient:St});return t.on("connection",(e=>{e.on("message",(t=>j(void 0,void 0,void 0,(function*(){be.verify(t.toString()),e.close()})))),setTimeout((()=>{e.close()}),2e3),e.on("close",(()=>{t.emit("close",e)}))})),t},St=(e,t)=>t(te),Tt=()=>j(void 0,void 0,void 0,(function*(){yield oe.sync();const e=It();te&&bt(e)}));export{k as API_AUTH_SLEEP,x as API_DB_DATABASE,D as API_DB_HOST,C as API_DB_LOG,B as API_DB_PASSWORD,G as API_DB_PORT,z as API_DB_TYPE,U as API_DB_USERNAME,F as API_HTTP_CROSS,L as API_HTTP_CRT,W as API_HTTP_HYBRID,H as API_HTTP_KEY,K as API_HTTP_PORT,M as API_HTTP_PUBLIC,X as API_TOKEN_CRT,J as API_TOKEN_HEADER,Y as API_TOKEN_KEY,V as API_TOKEN_LIFETIME,$ as API_UPLOAD_COUNT,Z as API_UPLOAD_FIELD,Q as API_UPLOAD_SIZE,ee as API_UPLOAD_TEMP,te as API_WEBSOCKET_START,se as Auth,ve as Config,ce as Configs,fe as Controller,ie as Group,ae as GroupRoute,pe as Log,le as Logs,he as Permission,ge as Responses,ne as Route,be as Token,de as User,ue as UserGroup,Te as auth,we as crt,Tt as initialize,Ie as key,Ae as permission,ht as router,oe as sequelize,bt as startSocket,Oe as upload,yt as useExpress,re as uuid,Ee as validation};
|
|
7
|
+
import{toBool as e,dateFormat as t,isArray as r,isString as o,noop as s,sleep as i,uniqueID as n,allowedObject as a,uuidv4 as d}from"@andrewcaires/utils.js";import{config as u}from"dotenv";import{UUID as c,UUIDV4 as l,Sequelize as m,DataTypes as p,Model as v,Op as g}from"sequelize";import*as f from"http";import*as h from"https";import{Server as y}from"net";import w from"cors";import I,{Router as b}from"express";import{existsSync as S,readFileSync as T}from"fs";import{SHA256 as A}from"crypto-js";import{sign as N,verify as O}from"jsonwebtoken";import E from"mime-types";import _ from"multer";import{join as P}from"path";import R from"joi";import q from"ws";function j(e,t,r,o){return new(r||(r=Promise))((function(s,i){function n(e){try{d(o.next(e))}catch(e){i(e)}}function a(e){try{d(o.throw(e))}catch(e){i(e)}}function d(e){var t;e.done?s(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,a)}d((o=o.apply(e,t||[])).next())}))}u();const k=parseInt(process.env.API_AUTH_SLEEP||"1000"),x=process.env.API_DB_DATABASE||"",D=process.env.API_DB_HOST||"127.0.0.1",B=process.env.API_DB_PASSWORD||"",G=parseInt(process.env.API_DB_PORT||"3306"),z=process.env.API_DB_TYPE||"",U=process.env.API_DB_USERNAME||"root",C=e(process.env.API_DB_LOG||"false"),L=process.env.API_HTTP_CRT||"",H=process.env.API_HTTP_KEY||"",K=parseInt(process.env.API_HTTP_PORT||"3000"),M=process.env.API_HTTP_PUBLIC||"",F=e(process.env.API_HTTP_CROSS||"false"),W=e(process.env.API_HTTP_HYBRID||"false"),X=process.env.API_TOKEN_CRT||"",Y=process.env.API_TOKEN_KEY||"",J=process.env.API_TOKEN_HEADER||"authorization",V=parseInt(process.env.API_TOKEN_LIFETIME||"15"),$=parseInt(process.env.API_UPLOAD_COUNT||"1"),Z=process.env.API_UPLOAD_FIELD||"upload",Q=parseInt(process.env.API_UPLOAD_SIZE||"2"),ee=process.env.API_UPLOAD_TEMP||"./temp",te=e(process.env.API_WEBSOCKET_START||"false"),re={type:c,defaultValue:l,allowNull:!1,primaryKey:!0},oe=(()=>{switch(z){case"mariadb":return new m(x,U,B,{host:D,port:G,dialect:"mariadb",logging:C,define:{timestamps:!1}});case"mysql":return new m(x,U,B,{host:D,port:G,dialect:"mysql",logging:C,define:{timestamps:!1}});case"postgres":return new m(x,U,B,{host:D,port:G,dialect:"postgres",logging:C,define:{timestamps:!1}})}throw new Error("No database selected")})();class se extends v{}se.init({login:p.BIGINT,logout:p.BIGINT,secret:p.STRING,timestamp:p.BIGINT,useragent:p.STRING},{sequelize:oe,modelName:"auth"});class ie extends v{}ie.init({name:p.STRING,description:p.TEXT,state:p.BOOLEAN},{sequelize:oe,modelName:"group"});class ne extends v{}ne.init({name:p.STRING,description:p.TEXT,state:p.BOOLEAN},{sequelize:oe,modelName:"route"});class ae extends v{}ae.init({},{sequelize:oe,modelName:"groups_routes"}),ae.removeAttribute("id");class de extends v{}de.init({name:p.STRING,email:p.STRING,username:p.STRING,password:p.STRING,description:p.TEXT,state:p.BOOLEAN},{sequelize:oe,modelName:"user"});class ue extends v{}ue.init({},{sequelize:oe,modelName:"users_groups"}),ue.removeAttribute("id");class ce extends v{}ce.init({key:p.STRING,value:p.STRING},{sequelize:oe,modelName:"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),ce.removeAttribute("id");class le extends v{}var me;le.init({type:p.STRING,source:p.STRING,message:p.TEXT},{sequelize:oe,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),de.hasMany(se),se.belongsTo(de),ie.hasMany(ae),ae.belongsTo(ie),ne.hasMany(ae),ae.belongsTo(ne),de.hasMany(ue),ue.belongsTo(de),ie.hasMany(ue),ue.belongsTo(ie),function(e){e.ERROR="[31m",e.INFO="[36m",e.NONE="[37m",e.SUCCESS="[32m",e.WARNING="[33m"}(me||(me={}));class pe{static write(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.NONE,"",e,t,r)}))}static error(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.ERROR,"error",e,t,r)}))}static info(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.INFO,"info",e,t,r)}))}static success(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.ERROR,"success",e,t,r)}))}static warning(e,t,r){return j(this,void 0,void 0,(function*(){yield pe.writeRaw(me.WARNING,"warning",e,t,r)}))}static writeConsole(e,r,o){const s=t(new Date,"%H:%M:%S");console.log(">",e,r+" ".repeat(10-r.length),"[37m","|",s,"|",o)}static writeRaw(e,t,r,o,s){return j(this,void 0,void 0,(function*(){s&&pe.writeConsole(e,t,r),yield le.create({type:t,source:o,message:r}).catch((()=>null))}))}}class ve{static all(){return j(this,void 0,void 0,(function*(){const e=yield ce.findAll().catch((e=>{pe.error(e.message,"api.config",!0)})),t={};return e&&e.forEach((e=>{t[e.key]=e.value})),t}))}static del(e){return j(this,void 0,void 0,(function*(){return((yield ce.destroy({where:{key:e}}).catch((e=>{pe.error(e.message,"api.config",!0)})))||0)>0}))}static get(e){return j(this,void 0,void 0,(function*(){const t=yield ce.findOne({where:{key:e}}).catch((e=>{pe.error(e.message,"api.config",!0)}));return t&&t.value||""}))}static set(e,t){return j(this,void 0,void 0,(function*(){const[r]=(yield ce.findOrCreate({where:{key:e}}).catch((e=>{pe.error(e.message,"api.config",!0)})))||[];r&&(r.value=t,yield r.save().catch((e=>{pe.error(e.message,"api.config",!0)})))}))}}class ge{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t,r){return e.status(400).json({message:t,details:r})}static unauthorized(e,t){return e.status(401).json({message:t})}}class fe{constructor(e){this.model=e}add(){return(e,t)=>j(this,void 0,void 0,(function*(){const r=yield this.model.create(e.body).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)}));return r?ge.data(t,{id:r.id}):ge.error(t,"Internal Server Error")}))}all(e,t){return(i,n)=>j(this,void 0,void 0,(function*(){var a,d,u,c,l;const m=Object.assign({},e||{});m.where=Object.assign({},m.where||{});const p=null===(a=i.query.limit)||void 0===a?void 0:a.toString();p&&(m.limit=parseInt(p));const v=null===(d=i.query.offset)||void 0===d?void 0:d.toString();v&&(m.offset=parseInt(v));const f=Object.keys(this.model.getAttributes()),h=[],y=null===(u=i.query.asc)||void 0===u?void 0:u.toString();y&&y.length&&y.split(",").forEach((e=>{f.indexOf(e)>=0&&h.push([e,"ASC"])}));const w=null===(c=i.query.desc)||void 0===c?void 0:c.toString();w&&w.length&&w.split(",").forEach((e=>{f.indexOf(e)>=0&&h.push([e,"DESC"])})),h.length&&(m.order=h);const I=[],b=r(m.attributes)?m.attributes:f,S=null===(l=i.query.search)||void 0===l?void 0:l.toString();b.forEach((e=>{var t;if(o(e)&&(S&&S.length&&I.push({[e]:{[g.like]:`%${S}%`}}),"search_"+e in i.query)){const r=null===(t=i.query["search_"+e])||void 0===t?void 0:t.toString();r&&r.length&&I.push({[e]:{[g.like]:`%${r}%`}})}})),I.length&&(m.where=Object.assign(Object.assign({},m.where),{[g.or]:[...I]}));const T=yield this.model.findAll(m).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)})),A=yield this.model.count(m).catch(s);return T?ge.data(n,{count:A,records:t?t(T):T}):ge.error(n,"Internal Server Error")}))}del(){return(e,t)=>j(this,void 0,void 0,(function*(){const{id:r}=e.params;return(yield this.model.destroy({where:{id:r}}).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)})))?ge.success(t,"OK"):ge.notfound(t,"Record not found")}))}get(e,t){return(r,o)=>j(this,void 0,void 0,(function*(){e||(e={});const s=Object.assign({},e);s.where=s.where?Object.assign({},s.where):{};const{id:i}=r.params,n=yield this.model.findByPk(i,s).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)}));return n?ge.data(o,t?t(n):n.toJSON()):null===n?ge.notfound(o,"Record not found"):ge.error(o,"Internal Server Error")}))}set(){return(e,t)=>j(this,void 0,void 0,(function*(){const{id:r}=e.params,[o]=(yield this.model.update(e.body,{where:{id:r}}).catch((e=>{pe.error(e.message,"api.controller."+this.model.tableName,!0)})))||[];return o?ge.success(t,"OK"):ge.success(t,"Record not changed")}))}}class he{static all(e,t){return j(this,void 0,void 0,(function*(){return yield ne.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:ae,required:!0,include:[{model:ie,required:!0,where:{state:!0},include:[{model:ue,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{pe.error(e.message,"api.permission",!0)}))}))}static get(e){return j(this,void 0,void 0,(function*(){const t=yield he.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return j(this,void 0,void 0,(function*(){const r=yield he.all(e,{name:t});return r&&!!r.length}))}}const ye=e=>{if(S(e))return T(e)},we={http:ye(L),token:ye(X)},Ie={http:ye(H),token:ye(Y)};class be{static sign(e){return Ie.token?{token:N(e,Ie.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static verify(e){if(!we.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:O(e,we.token)}}catch(e){return{error:"Invalid Token"}}}}const Se=["id","name","email","username"],Te=(e,t,r)=>j(void 0,void 0,void 0,(function*(){const o=e.get(J)||"",{error:s,decode:i}=be.verify(o);if(s)return ge.error(t,s);if(i){const{id:o,secret:s}=i;if(o&&i){const i=yield de.findOne({where:{id:o,state:!0}}).catch((e=>{pe.error(e.message,"api.auth",!0)}));if(i){const o=yield se.findOne({where:{secret:s,userId:i.id}}).catch((e=>{pe.error(e.message,"api.auth",!0)}));if(o){const s=Date.now();if(s>o.timestamp)return ge.error(t,"Expired token");if(!o.logout){o.timestamp=s+6e4*V;const t=e.get("User-Agent");return t&&(o.useragent=t),yield o.save(),e.auth=o,e.user=i,r()}}}return ge.error(t,"Access denied")}}return ge.error(t,"Invalid token")})),Ae=e=>(t,r,o)=>j(void 0,void 0,void 0,(function*(){const s=t.user;return s?(yield he.is(s,e))?o():ge.error(r,"Unauthorized access"):ge.unauthorized(r,"Access denied")})),Ne=(e,t)=>{const r=d()+"."+t;return S(P(e,r))?Ne(e,t):r},Oe=e=>{const t=(null==e?void 0:e.path)||ee,r=_.diskStorage({destination:(e,r,o)=>o(null,t),filename:(e,r,o)=>j(void 0,void 0,void 0,(function*(){return o(null,Ne(t,E.extension(r.mimetype)||"bin"))}))}),o=1e6*((null==e?void 0:e.size)||Q),s=_({storage:r,fileFilter(t,r,o){var s;return j(this,void 0,void 0,(function*(){const t=null===(s=null==e?void 0:e.types)||void 0===s?void 0:s.indexOf(r.mimetype);return void 0!==t&&t<0?o(new Error("File type not allowed")):o(null,!0)}))},limits:{fileSize:o}}),i=(null==e?void 0:e.count)||$,n=(null==e?void 0:e.field)||Z,a=s.array(n,i);return(e,t,r)=>{a(e,t,(function(e){return e?ge.error(t,e.message):r()}))}},Ee=e=>{const t={abortEarly:!1,allowUnknown:!0,stripUnknown:!0};return(r,o,s)=>{const{error:i,value:n}=e.validate(r.body,t);if(i){const e=i.details.map((e=>e.message)).join(", "),t=[];return i.details.forEach((e=>{var r;t.push({key:(null===(r=e.context)||void 0===r?void 0:r.key)||"",type:e.type})})),ge.validation(o,"Validation error: "+e,t)}return r.body=n,s()}},_e={username:R.string().min(5).required(),password:R.string().min(5).required()},Pe=Ee(R.object(_e)),Re=b();Re.get("/",Te,((e,t)=>j(void 0,void 0,void 0,(function*(){const r=e.user;if(!r)return ge.unauthorized(t,"Access denied");const o=yield he.all(r);if(o){const e=a(Se,r.toJSON()),s=o.map((e=>e.name));return ge.data(t,Object.assign(Object.assign({},e),{permissions:s}))}return ge.error(t,"Internal Server Error")})))),Re.post("/login",Pe,((e,t)=>j(void 0,void 0,void 0,(function*(){const{username:r,password:o}=e.body;if(!r||!o)return ge.error(t,"Invalid parameters");yield i(k);const s=yield de.findOne({where:{username:r}}).catch((e=>{pe.error(e.message,"api.controller."+de.tableName,!0)}));if(!s)return ge.notfound(t,"Username not found");if(!s.state)return ge.error(t,"Username is disabled");const a=A(o).toString();if(s.password!=a)return ge.error(t,"Invalid password");const d=s.id,u=n(),{error:c,token:l}=be.sign({id:d,secret:u});if(c)return ge.error(t,c);if(l){const r=Date.now(),o=r+6e4*V,s=e.get("User-Agent"),i=yield se.create({login:r,secret:u,timestamp:o,useragent:s,userId:d}).catch((e=>{pe.error(e.message,"api.controller."+se.tableName,!0)}));if(i)return ge.data(t,{token:l})}return ge.error(t,"Internal Server Error")})))),Re.get("/logout",Te,((e,t)=>j(void 0,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),ge.success(t,"Disconcerted")):ge.unauthorized(t,"Access denied")}))));const qe=new fe(ie),je=new fe(ae),ke=qe.add(),xe=qe.all(),De=qe.del(),Be=qe.get(),Ge=qe.set(),ze={name:R.string().min(3).required(),description:R.string().allow(null,""),state:R.boolean().required()},Ue=Ee(R.object(ze)),Ce={routes:R.array().items(R.number())},Le=Ee(R.object(Ce)),He={name:R.string().min(3).empty(""),description:R.string().allow(null,""),state:R.boolean().empty("")},Ke=Ee(R.object(He)),Me=b();Me.use(Te),Me.get("/",Ae("groups.read"),xe),Me.post("/",Ae("groups.write"),Ue,ke),Me.route("/:id").get(Ae("groups.read"),Be).put(Ae("groups.write"),Ke,Ge).delete(Ae("groups.write"),De),Me.route("/:id/routes").get(Ae("groups.read"),Le,((e,t)=>j(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return je.all({where:{groupId:r},include:[{model:ne,required:!0}]},(e=>e.map((e=>e.route))))(e,t)})))).put(Ae("groups.write"),Le,((e,t)=>j(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{routes:o}=e.body,s=yield ie.findByPk(r,{attributes:["id"]}).catch((e=>{pe.error(e.message,"api.controller."+ie.tableName,!0)}));if(s){const e=s.id;if(yield ae.destroy({where:{groupId:e}}),o){let t=0;for(let r=0;r<o.length;r++)t=yield ne.count({where:{id:o[r]}}),t&&(yield ae.create({groupId:e,routeId:o[r]}))}return ge.success(t,"OK")}return null===s?ge.notfound(t,"Record not found"):ge.error(t,"Internal Server Error")}))));const Fe=new fe(le),We=b();We.use(Te),We.get("/",Ae("logs.read"),((e,t)=>j(void 0,void 0,void 0,(function*(){const{source:r,type:o}=e.query,s=r&&o?{source:r,type:o}:r?{source:r}:o?{type:o}:{};return Fe.all({where:s,order:[["created","DESC"]]})(e,t)}))));const Xe=new fe(ne),Ye=Xe.add(),Je=Xe.all(),Ve=Xe.del(),$e=Xe.get(),Ze=Xe.set(),Qe={name:R.string().min(5).required(),description:R.string().allow(null,""),state:R.boolean().required()},et=Ee(R.object(Qe)),tt={name:R.string().min(5).empty(""),description:R.string().allow(null,""),state:R.boolean().empty("")},rt=Ee(R.object(tt)),ot=b();ot.use(Te),ot.get("/",Ae("routes.read"),Je),ot.post("/",Ae("routes.write"),et,Ye),ot.route("/:id").get(Ae("routes.read"),$e).put(Ae("routes.write"),rt,Ze).delete(Ae("routes.write"),Ve);const st=new fe(de),it=new fe(ue),nt=["id","name","email","username","description","state"],at={name:R.string().min(5).required(),email:R.string().email().required(),username:R.string().min(5).required(),password:R.string().min(5).required(),description:R.string().allow(null,""),state:R.boolean().required()},dt=Ee(R.object(at)),ut={groups:R.array().items(R.number())},ct=Ee(R.object(ut)),lt={name:R.string().min(5).empty(""),email:R.string().email().empty(""),username:R.string().min(5).empty(""),password:R.string().min(5).empty(""),description:R.string().allow(null,""),state:R.boolean().empty("")},mt=Ee(R.object(lt)),pt=b();pt.use(Te),pt.get("/",Ae("users.read"),((e,t)=>j(void 0,void 0,void 0,(function*(){return st.all({attributes:nt})(e,t)})))),pt.post("/",Ae("users.write"),dt,((e,t)=>j(void 0,void 0,void 0,(function*(){return e.body.password=A(e.body.password).toString(),yield st.add()(e,t)})))),pt.route("/:id").get(Ae("users.read"),((e,t)=>j(void 0,void 0,void 0,(function*(){return st.get({attributes:nt})(e,t)})))).put(Ae("users.write"),mt,((e,t)=>j(void 0,void 0,void 0,(function*(){return e.body.password&&(e.body.password=A(e.body.password).toString()),st.set()(e,t)})))).delete(Ae("users.write"),((e,t)=>j(void 0,void 0,void 0,(function*(){const r=e.user;if(r){const{id:o}=e.params;if(r.id.toString()!=o)return st.del()(e,t)}return ge.error(t,"Internal Server Error")})))),pt.route("/:id/groups").get(Ae("users.read"),((e,t)=>j(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return it.all({where:{userId:r},include:[{model:ie,required:!0}]},(e=>e.map((e=>e.group))))(e,t)})))).put(Ae("users.write"),ct,((e,t)=>j(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{groups:o}=e.body,s=yield de.findByPk(r,{attributes:["id"]}).catch((e=>{pe.error(e.message,"api.controller."+de.tableName,!0)}));if(s){if(yield ue.destroy({where:{userId:s.id}}),o){let e=0;for(let t=0;t<o.length;t++)e=yield ie.count({where:{id:o[t]}}),e&&(yield ue.create({userId:s.id,groupId:o[t]}))}return ge.success(t,"OK")}return ge.notfound(t,"Record not found")}))));const vt=b();let gt;vt.use("/auth",Re),vt.use("/groups",Me),vt.use("/logs",We),vt.use("/routes",ot),vt.use("/users",pt);const ft=b(),ht=()=>{var e;return gt||(gt=I(),(e=gt).use(I.json()),e.use(((e,t,r,o)=>e?(pe.error(e.message,"api.express",!0),ge.error(r,"Internal Server Error")):o())),e.use(I.urlencoded({extended:!0})),e.disable("x-powered-by"),F&&e.use(w()),e.use("/api",ft),e.use("/api",vt),e.all("/api/*",((e,t)=>ge.notfound(t,"Invalid API"))),M&&(S(M)&&e.use(I.static(M)),e.get("*",((e,t)=>{if(!S(M))return ge.notfound(t,'File "index.html" not found');t.sendFile(M+"/index.html")})))),gt};let yt;const wt=()=>(yt||(yt=(e=>{if(!we.http||!Ie.http){const t=f.createServer(e);return t.listen(K,(()=>pe.info("Server started on port "+K,"api.server",!0))),t}const t=f.createServer(((e,t)=>{const r=80==K?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),r=h.createServer({key:Ie.http,cert:we.http},e);if(W)return new y((e=>{e.once("data",(o=>{e.pause(),e.unshift(o),(22===o[0]?r:t).emit("connection",e),process.nextTick((()=>e.resume()))}))})).listen(K,(()=>pe.info("Server started on port "+K,"api.server",!0))),r;return 443==K&&t.listen(80,(()=>pe.info("Server started on port 80","api.server",!0))),r.listen(K,(()=>pe.info("Server started on port "+K,"api.server",!0))),r})(ht())),yt),It=e=>{const t=new q.Server({server:e,verifyClient:bt});return t.on("connection",(e=>{e.on("message",(t=>j(void 0,void 0,void 0,(function*(){be.verify(t.toString()),e.close()})))),setTimeout((()=>{e.close()}),2e3),e.on("close",(()=>{t.emit("close",e)}))})),t},bt=(e,t)=>t(te),St=()=>j(void 0,void 0,void 0,(function*(){yield oe.sync();const e=wt();te&&It(e)}));export{k as API_AUTH_SLEEP,x as API_DB_DATABASE,D as API_DB_HOST,C as API_DB_LOG,B as API_DB_PASSWORD,G as API_DB_PORT,z as API_DB_TYPE,U as API_DB_USERNAME,F as API_HTTP_CROSS,L as API_HTTP_CRT,W as API_HTTP_HYBRID,H as API_HTTP_KEY,K as API_HTTP_PORT,M as API_HTTP_PUBLIC,X as API_TOKEN_CRT,J as API_TOKEN_HEADER,Y as API_TOKEN_KEY,V as API_TOKEN_LIFETIME,$ as API_UPLOAD_COUNT,Z as API_UPLOAD_FIELD,Q as API_UPLOAD_SIZE,ee as API_UPLOAD_TEMP,te as API_WEBSOCKET_START,se as Auth,ve as Config,ce as Configs,fe as Controller,ie as Group,ae as GroupRoute,pe as Log,le as Logs,he as Permission,ge as Responses,ne as Route,be as Token,de as User,ue as UserGroup,Te as auth,we as crt,St as initialize,Ie as key,Ae as permission,ft as router,oe as sequelize,It as startSocket,Oe as upload,ht as useExpress,re as uuid,Ee as validation};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/api v1.0.
|
|
2
|
+
* @andrewcaires/api v1.0.7
|
|
3
3
|
* Simple api for small applications using express, jsonwebtoken, sequelize and websocket
|
|
4
4
|
* (c) 2022 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
6
6
|
*/
|
|
7
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@andrewcaires/utils.js"),t=require("dotenv"),r=require("sequelize"),s=require("http"),o=require("https"),i=require("net"),n=require("cors"),a=require("express"),d=require("fs"),u=require("crypto-js"),l=require("jsonwebtoken"),c=require("mime-types"),p=require("multer"),f=require("path"),m=require("joi"),v=require("ws");function g(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function y(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var h=y(s),I=y(o),T=g(n),w=g(a),_=g(c),A=g(p),P=g(m),S=g(v);function b(e,t,r,s){return new(r||(r=Promise))((function(o,i){function n(e){try{d(s.next(e))}catch(e){i(e)}}function a(e){try{d(s.throw(e))}catch(e){i(e)}}function d(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,a)}d((s=s.apply(e,t||[])).next())}))}t.config();const O=parseInt(process.env.API_AUTH_SLEEP||"1000"),x=process.env.API_DB_DATABASE||"",E=process.env.API_DB_HOST||"127.0.0.1",D=process.env.API_DB_PASSWORD||"",R=parseInt(process.env.API_DB_PORT||"3306"),N=process.env.API_DB_TYPE||"",q=process.env.API_DB_USERNAME||"root",j=e.toBool(process.env.API_DB_LOG||"false"),k=process.env.API_HTTP_CRT||"",B=process.env.API_HTTP_KEY||"",U=parseInt(process.env.API_HTTP_PORT||"3000"),H=process.env.API_HTTP_PUBLIC||"",C=e.toBool(process.env.API_HTTP_CROSS||"false"),L=e.toBool(process.env.API_HTTP_HYBRID||"false"),z=process.env.API_TOKEN_CRT||"",G=process.env.API_TOKEN_KEY||"",M=process.env.API_TOKEN_HEADER||"authorization",K=parseInt(process.env.API_TOKEN_LIFETIME||"15"),F=parseInt(process.env.API_UPLOAD_COUNT||"1"),Y=process.env.API_UPLOAD_FIELD||"upload",W=parseInt(process.env.API_UPLOAD_SIZE||"2"),X=process.env.API_UPLOAD_TEMP||"./temp",V=e.toBool(process.env.API_WEBSOCKET_START||"false"),J={type:r.UUID,defaultValue:r.UUIDV4,allowNull:!1,primaryKey:!0},Z=(()=>{switch(N){case"mariadb":return new r.Sequelize(x,q,D,{host:E,port:R,dialect:"mariadb",logging:j,define:{timestamps:!1}});case"mysql":return new r.Sequelize(x,q,D,{host:E,port:R,dialect:"mysql",logging:j,define:{timestamps:!1}});case"postgres":return new r.Sequelize(x,q,D,{host:E,port:R,dialect:"postgres",logging:j,define:{timestamps:!1}})}throw new Error("No database selected")})();class $ extends r.Model{}$.init({login:r.DataTypes.BIGINT,logout:r.DataTypes.BIGINT,secret:r.DataTypes.STRING,timestamp:r.DataTypes.BIGINT,useragent:r.DataTypes.STRING},{sequelize:Z,modelName:"auth"});class Q extends r.Model{}Q.init({name:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:Z,modelName:"group"});class ee extends r.Model{}ee.init({name:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:Z,modelName:"route"});class te extends r.Model{}te.init({},{sequelize:Z,modelName:"groups_routes"}),te.removeAttribute("id");class re extends r.Model{}re.init({name:r.DataTypes.STRING,email:r.DataTypes.STRING,username:r.DataTypes.STRING,password:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:Z,modelName:"user"});class se extends r.Model{}se.init({},{sequelize:Z,modelName:"users_groups"}),se.removeAttribute("id");class oe extends r.Model{}oe.init({key:r.DataTypes.STRING,value:r.DataTypes.STRING},{sequelize:Z,modelName:"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),oe.removeAttribute("id");class ie extends r.Model{}var ne;ie.init({type:r.DataTypes.STRING,source:r.DataTypes.STRING,message:r.DataTypes.TEXT},{sequelize:Z,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),re.hasMany($),$.belongsTo(re),Q.hasMany(te),te.belongsTo(Q),ee.hasMany(te),te.belongsTo(ee),re.hasMany(se),se.belongsTo(re),Q.hasMany(se),se.belongsTo(Q),function(e){e.ERROR="[31m",e.INFO="[36m",e.NONE="[37m",e.SUCCESS="[32m",e.WARNING="[33m"}(ne||(ne={}));class ae{static write(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.NONE,"",e,t,r)}))}static error(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.ERROR,"error",e,t,r)}))}static info(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.INFO,"info",e,t,r)}))}static success(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.ERROR,"success",e,t,r)}))}static warning(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.WARNING,"warning",e,t,r)}))}static writeConsole(t,r,s){const o=e.dateFormat(new Date,"%H:%M:%S");console.log(">",t,r+" ".repeat(10-r.length),"[37m","|",o,"|",s)}static writeRaw(e,t,r,s,o){return b(this,void 0,void 0,(function*(){o&&ae.writeConsole(e,t,r),yield ie.create({type:t,source:s,message:r}).catch((()=>null))}))}}class de{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t,r){return e.status(400).json({message:t,details:r})}static unauthorized(e,t){return e.status(401).json({message:t})}}class ue{constructor(e){this.model=e}add(){return(e,t)=>b(this,void 0,void 0,(function*(){const r=yield this.model.create(e.body).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)}));return r?de.data(t,{id:r.id}):de.error(t,"Internal Server Error")}))}all(t,s){return(o,i)=>b(this,void 0,void 0,(function*(){var n,a,d,u,l;const c=Object.assign({},t||{});c.where=Object.assign({},c.where||{});const p=null===(n=o.query.limit)||void 0===n?void 0:n.toString();p&&(c.limit=parseInt(p));const f=null===(a=o.query.offset)||void 0===a?void 0:a.toString();f&&(c.offset=parseInt(f));const m=Object.keys(this.model.getAttributes()),v=[],g=null===(d=o.query.asc)||void 0===d?void 0:d.toString();g&&g.length&&g.split(",").forEach((e=>{m.indexOf(e)>=0&&v.push([e,"ASC"])}));const y=null===(u=o.query.desc)||void 0===u?void 0:u.toString();y&&y.length&&y.split(",").forEach((e=>{m.indexOf(e)>=0&&v.push([e,"DESC"])})),v.length&&(c.order=v);const h=[],I=e.isArray(c.attributes)?c.attributes:m,T=null===(l=o.query.search)||void 0===l?void 0:l.toString();I.forEach((t=>{var s;if(e.isString(t)&&(T&&T.length&&h.push({[t]:{[r.Op.like]:`%${T}%`}}),"search_"+t in o.query)){const e=null===(s=o.query["search_"+t])||void 0===s?void 0:s.toString();e&&e.length&&h.push({[t]:{[r.Op.like]:`%${e}%`}})}})),h.length&&(c.where=Object.assign(Object.assign({},c.where),{[r.Op.or]:[...h]}));const w=yield this.model.findAll(c).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)})),_=yield this.model.count(c).catch(e.noop);return w?de.data(i,{count:_,records:s?s(w):w}):de.error(i,"Internal Server Error")}))}del(){return(e,t)=>b(this,void 0,void 0,(function*(){const{id:r}=e.params;return(yield this.model.destroy({where:{id:r}}).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)})))?de.success(t,"OK"):de.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>b(this,void 0,void 0,(function*(){e||(e={});const o=Object.assign({},e);o.where=o.where?Object.assign({},o.where):{};const{id:i}=r.params,n=yield this.model.findByPk(i,o).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)}));return n?de.data(s,t?t(n):n.toJSON()):null===n?de.notfound(s,"Record not found"):de.error(s,"Internal Server Error")}))}set(){return(e,t)=>b(this,void 0,void 0,(function*(){const{id:r}=e.params,[s]=(yield this.model.update(e.body,{where:{id:r}}).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)})))||[];return s?de.success(t,"OK"):de.success(t,"Record not changed")}))}}class le{static all(e,t){return b(this,void 0,void 0,(function*(){return yield ee.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:te,required:!0,include:[{model:Q,required:!0,where:{state:!0},include:[{model:se,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{ae.error(e.message,"api.permission",!0)}))}))}static get(e){return b(this,void 0,void 0,(function*(){const t=yield le.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return b(this,void 0,void 0,(function*(){const r=yield le.all(e,{name:t});return r&&!!r.length}))}}const ce=e=>{if(d.existsSync(e))return d.readFileSync(e)},pe={http:ce(k),token:ce(z)},fe={http:ce(B),token:ce(G)};class me{static sign(e){return fe.token?{token:l.sign(e,fe.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static verify(e){if(!pe.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:l.verify(e,pe.token)}}catch(e){return{error:"Invalid Token"}}}}const ve=["id","name","email","username"],ge=(e,t,r)=>b(void 0,void 0,void 0,(function*(){const s=e.get(M)||"",{error:o,decode:i}=me.verify(s);if(o)return de.error(t,o);if(i){const{id:s,secret:o}=i;if(s&&i){const i=yield re.findOne({where:{id:s,state:!0}}).catch((e=>{ae.error(e.message,"api.auth",!0)}));if(i){const s=yield $.findOne({where:{secret:o,userId:i.id}}).catch((e=>{ae.error(e.message,"api.auth",!0)}));if(s){const o=Date.now();if(o>s.timestamp)return de.error(t,"Expired token");if(!s.logout){s.timestamp=o+6e4*K;const t=e.get("User-Agent");return t&&(s.useragent=t),yield s.save(),e.auth=s,e.user=i,r()}}}return de.error(t,"Access denied")}}return de.error(t,"Invalid token")})),ye=e=>(t,r,s)=>b(void 0,void 0,void 0,(function*(){const o=t.user;return o?(yield le.is(o,e))?s():de.error(r,"Unauthorized access"):de.unauthorized(r,"Access denied")})),he=(t,r)=>{const s=e.uuidv4()+"."+r;return d.existsSync(f.join(t,s))?he(t,r):s},Ie=e=>{const t={abortEarly:!1,allowUnknown:!0,stripUnknown:!0};return(r,s,o)=>{const{error:i,value:n}=e.validate(r.body,t);if(i){const e=i.details.map((e=>e.message)).join(", "),t=[];return i.details.forEach((e=>{var r;t.push({key:(null===(r=e.context)||void 0===r?void 0:r.key)||"",type:e.type})})),de.validation(s,"Validation error: "+e,t)}return r.body=n,o()}},Te={username:P.default.string().min(5).required(),password:P.default.string().min(5).required()},we=Ie(P.default.object(Te)),_e=a.Router();_e.get("/",ge,((t,r)=>b(void 0,void 0,void 0,(function*(){const s=t.user;if(!s)return de.unauthorized(r,"Access denied");const o=yield le.all(s);if(o){const t=e.allowedObject(ve,s.toJSON()),i=o.map((e=>e.name));return de.data(r,Object.assign(Object.assign({},t),{permissions:i}))}return de.error(r,"Internal Server Error")})))),_e.post("/login",we,((t,r)=>b(void 0,void 0,void 0,(function*(){const{username:s,password:o}=t.body;if(!s||!o)return de.error(r,"Invalid parameters");yield e.sleep(O);const i=yield re.findOne({where:{username:s}}).catch((e=>{ae.error(e.message,"api.controller."+re.tableName,!0)}));if(!i)return de.notfound(r,"Username not found");if(!i.state)return de.error(r,"Username is disabled");const n=u.SHA256(o).toString();if(i.password!=n)return de.error(r,"Invalid password");const a=i.id,d=e.uniqueID(),{error:l,token:c}=me.sign({id:a,secret:d});if(l)return de.error(r,l);if(c){const e=Date.now(),s=e+6e4*K,o=t.get("User-Agent"),i=yield $.create({login:e,secret:d,timestamp:s,useragent:o,userId:a}).catch((e=>{ae.error(e.message,"api.controller."+$.tableName,!0)}));if(i)return de.data(r,{token:c})}return de.error(r,"Internal Server Error")})))),_e.get("/logout",ge,((e,t)=>b(void 0,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),de.success(t,"Disconcerted")):de.unauthorized(t,"Access denied")}))));const Ae=new ue(Q),Pe=new ue(te),Se=Ae.add(),be=Ae.all(),Oe=Ae.del(),xe=Ae.get(),Ee=Ae.set(),De={name:P.default.string().min(3).required(),description:P.default.string().allow(null,""),state:P.default.boolean().required()},Re=Ie(P.default.object(De)),Ne={routes:P.default.array().items(P.default.number())},qe=Ie(P.default.object(Ne)),je={name:P.default.string().min(3).empty(""),description:P.default.string().allow(null,""),state:P.default.boolean().empty("")},ke=Ie(P.default.object(je)),Be=a.Router();Be.use(ge),Be.get("/",ye("groups.read"),be),Be.post("/",ye("groups.write"),Re,Se),Be.route("/:id").get(ye("groups.read"),xe).put(ye("groups.write"),ke,Ee).delete(ye("groups.write"),Oe),Be.route("/:id/routes").get(ye("groups.read"),qe,((e,t)=>b(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return Pe.all({where:{groupId:r},include:[{model:ee,required:!0}]},(e=>e.map((e=>e.route))))(e,t)})))).put(ye("groups.write"),qe,((e,t)=>b(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,o=yield Q.findByPk(r,{attributes:["id"]}).catch((e=>{ae.error(e.message,"api.controller."+Q.tableName,!0)}));if(o){const e=o.id;if(yield te.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield ee.count({where:{id:s[r]}}),t&&(yield te.create({groupId:e,routeId:s[r]}))}return de.success(t,"OK")}return null===o?de.notfound(t,"Record not found"):de.error(t,"Internal Server Error")}))));const Ue=new ue(ie),He=a.Router();He.use(ge),He.get("/",ye("logs.read"),((e,t)=>b(void 0,void 0,void 0,(function*(){const{source:r,type:s}=e.query,o=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return Ue.all({where:o,order:[["created","DESC"]]})(e,t)}))));const Ce=new ue(ee),Le=Ce.add(),ze=Ce.all(),Ge=Ce.del(),Me=Ce.get(),Ke=Ce.set(),Fe={name:P.default.string().min(5).required(),description:P.default.string().allow(null,""),state:P.default.boolean().required()},Ye=Ie(P.default.object(Fe)),We={name:P.default.string().min(5).empty(""),description:P.default.string().allow(null,""),state:P.default.boolean().empty("")},Xe=Ie(P.default.object(We)),Ve=a.Router();Ve.use(ge),Ve.get("/",ye("routes.read"),ze),Ve.post("/",ye("routes.write"),Ye,Le),Ve.route("/:id").get(ye("routes.read"),Me).put(ye("routes.write"),Xe,Ke).delete(ye("routes.write"),Ge);const Je=new ue(re),Ze=new ue(se),$e=["id","name","email","username","description","state"],Qe=Je.del(),et={name:P.default.string().min(5).required(),email:P.default.string().email().required(),username:P.default.string().min(5).required(),password:P.default.string().min(5).required(),description:P.default.string().allow(null,""),state:P.default.boolean().required()},tt=Ie(P.default.object(et)),rt={groups:P.default.array().items(P.default.number())},st=Ie(P.default.object(rt)),ot={name:P.default.string().min(5).empty(""),email:P.default.string().email().empty(""),username:P.default.string().min(5).empty(""),password:P.default.string().min(5).empty(""),description:P.default.string().allow(null,""),state:P.default.boolean().empty("")},it=Ie(P.default.object(ot)),nt=a.Router();nt.use(ge),nt.get("/",ye("users.read"),((e,t)=>b(void 0,void 0,void 0,(function*(){return Je.all({attributes:$e})(e,t)})))),nt.post("/",ye("users.write"),tt,((e,t)=>b(void 0,void 0,void 0,(function*(){return e.body.password=u.SHA256(e.body.password).toString(),yield Je.add()(e,t)})))),nt.route("/:id").get(ye("users.read"),((e,t)=>b(void 0,void 0,void 0,(function*(){return Je.get({attributes:$e})(e,t)})))).put(ye("users.write"),it,((e,t)=>b(void 0,void 0,void 0,(function*(){return e.body.password&&(e.body.password=u.SHA256(e.body.password).toString()),Je.set()(e,t)})))).delete(ye("users.write"),Qe),nt.route("/:id/groups").get(ye("users.read"),((e,t)=>b(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return Ze.all({where:{userId:r},include:[{model:Q,required:!0}]},(e=>e.map((e=>e.group))))(e,t)})))).put(ye("users.write"),st,((e,t)=>b(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,o=yield re.findByPk(r,{attributes:["id"]}).catch((e=>{ae.error(e.message,"api.controller."+re.tableName,!0)}));if(o){if(yield se.destroy({where:{userId:o.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield Q.count({where:{id:s[t]}}),e&&(yield se.create({userId:o.id,groupId:s[t]}))}return de.success(t,"OK")}return de.notfound(t,"Record not found")}))));const at=a.Router();let dt;at.use("/auth",_e),at.use("/groups",Be),at.use("/logs",He),at.use("/routes",Ve),at.use("/users",nt);const ut=a.Router(),lt=()=>{var e;return dt||(dt=w.default(),(e=dt).use(w.default.json()),e.use(((e,t,r,s)=>e?(ae.error(e.message,"api.express",!0),de.error(r,"Internal Server Error")):s())),e.use(w.default.urlencoded({extended:!0})),e.disable("x-powered-by"),C&&e.use(T.default()),e.use("/api",ut),e.use("/api",at),e.all("/api/*",((e,t)=>de.notfound(t,"Invalid API"))),H&&(d.existsSync(H)&&e.use(w.default.static(H)),e.get("*",((e,t)=>{if(!d.existsSync(H))return de.notfound(t,'File "index.html" not found');t.sendFile(H+"/index.html")})))),dt};let ct;const pt=()=>(ct||(ct=(e=>{if(!pe.http||!fe.http){const t=h.createServer(e);return t.listen(U,(()=>ae.info("Server started on port "+U,"api.server",!0))),t}const t=h.createServer(((e,t)=>{const r=80==U?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),r=I.createServer({key:fe.http,cert:pe.http},e);if(L)return new i.Server((e=>{e.once("data",(s=>{e.pause(),e.unshift(s),(22===s[0]?r:t).emit("connection",e),process.nextTick((()=>e.resume()))}))})).listen(U,(()=>ae.info("Server started on port "+U,"api.server",!0))),r;return 443==U&&t.listen(80,(()=>ae.info("Server started on port 80","api.server",!0))),r.listen(U,(()=>ae.info("Server started on port "+U,"api.server",!0))),r})(lt())),ct),ft=e=>{const t=new S.default.Server({server:e,verifyClient:mt});return t.on("connection",(e=>{e.on("message",(t=>b(void 0,void 0,void 0,(function*(){me.verify(t.toString()),e.close()})))),setTimeout((()=>{e.close()}),2e3),e.on("close",(()=>{t.emit("close",e)}))})),t},mt=(e,t)=>t(V);exports.API_AUTH_SLEEP=O,exports.API_DB_DATABASE=x,exports.API_DB_HOST=E,exports.API_DB_LOG=j,exports.API_DB_PASSWORD=D,exports.API_DB_PORT=R,exports.API_DB_TYPE=N,exports.API_DB_USERNAME=q,exports.API_HTTP_CROSS=C,exports.API_HTTP_CRT=k,exports.API_HTTP_HYBRID=L,exports.API_HTTP_KEY=B,exports.API_HTTP_PORT=U,exports.API_HTTP_PUBLIC=H,exports.API_TOKEN_CRT=z,exports.API_TOKEN_HEADER=M,exports.API_TOKEN_KEY=G,exports.API_TOKEN_LIFETIME=K,exports.API_UPLOAD_COUNT=F,exports.API_UPLOAD_FIELD=Y,exports.API_UPLOAD_SIZE=W,exports.API_UPLOAD_TEMP=X,exports.API_WEBSOCKET_START=V,exports.Auth=$,exports.Config=class{static all(){return b(this,void 0,void 0,(function*(){const e=yield oe.findAll().catch((e=>{ae.error(e.message,"api.config",!0)})),t={};return e&&e.forEach((e=>{t[e.key]=e.value})),t}))}static del(e){return b(this,void 0,void 0,(function*(){return((yield oe.destroy({where:{key:e}}).catch((e=>{ae.error(e.message,"api.config",!0)})))||0)>0}))}static get(e){return b(this,void 0,void 0,(function*(){const t=yield oe.findOne({where:{key:e}}).catch((e=>{ae.error(e.message,"api.config",!0)}));return t&&t.value||""}))}static set(e,t){return b(this,void 0,void 0,(function*(){const[r]=(yield oe.findOrCreate({where:{key:e}}).catch((e=>{ae.error(e.message,"api.config",!0)})))||[];r&&(r.value=t,yield r.save().catch((e=>{ae.error(e.message,"api.config",!0)})))}))}},exports.Configs=oe,exports.Controller=ue,exports.Group=Q,exports.GroupRoute=te,exports.Log=ae,exports.Logs=ie,exports.Permission=le,exports.Responses=de,exports.Route=ee,exports.Token=me,exports.User=re,exports.UserGroup=se,exports.auth=ge,exports.crt=pe,exports.initialize=()=>b(void 0,void 0,void 0,(function*(){yield Z.sync();const e=pt();V&&ft(e)})),exports.key=fe,exports.permission=ye,exports.router=ut,exports.sequelize=Z,exports.startSocket=ft,exports.upload=e=>{const t=(null==e?void 0:e.path)||X,r=A.default.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>b(void 0,void 0,void 0,(function*(){return s(null,he(t,_.default.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||W),o=A.default({storage:r,fileFilter(t,r,s){var o;return b(this,void 0,void 0,(function*(){const t=null===(o=null==e?void 0:e.types)||void 0===o?void 0:o.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),i=(null==e?void 0:e.count)||F,n=(null==e?void 0:e.field)||Y,a=o.array(n,i);return(e,t,r)=>{a(e,t,(function(e){return e?de.error(t,e.message):r()}))}},exports.useExpress=lt,exports.uuid=J,exports.validation=Ie;
|
|
7
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@andrewcaires/utils.js"),t=require("dotenv"),r=require("sequelize"),s=require("http"),o=require("https"),i=require("net"),n=require("cors"),a=require("express"),d=require("fs"),u=require("crypto-js"),l=require("jsonwebtoken"),c=require("mime-types"),p=require("multer"),f=require("path"),v=require("joi"),m=require("ws");function g(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function y(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var h=y(s),I=y(o),T=g(n),w=g(a),_=g(c),A=g(p),P=g(v),S=g(m);function b(e,t,r,s){return new(r||(r=Promise))((function(o,i){function n(e){try{d(s.next(e))}catch(e){i(e)}}function a(e){try{d(s.throw(e))}catch(e){i(e)}}function d(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,a)}d((s=s.apply(e,t||[])).next())}))}t.config();const O=parseInt(process.env.API_AUTH_SLEEP||"1000"),x=process.env.API_DB_DATABASE||"",E=process.env.API_DB_HOST||"127.0.0.1",D=process.env.API_DB_PASSWORD||"",R=parseInt(process.env.API_DB_PORT||"3306"),N=process.env.API_DB_TYPE||"",q=process.env.API_DB_USERNAME||"root",j=e.toBool(process.env.API_DB_LOG||"false"),k=process.env.API_HTTP_CRT||"",B=process.env.API_HTTP_KEY||"",U=parseInt(process.env.API_HTTP_PORT||"3000"),H=process.env.API_HTTP_PUBLIC||"",C=e.toBool(process.env.API_HTTP_CROSS||"false"),L=e.toBool(process.env.API_HTTP_HYBRID||"false"),z=process.env.API_TOKEN_CRT||"",G=process.env.API_TOKEN_KEY||"",M=process.env.API_TOKEN_HEADER||"authorization",K=parseInt(process.env.API_TOKEN_LIFETIME||"15"),F=parseInt(process.env.API_UPLOAD_COUNT||"1"),Y=process.env.API_UPLOAD_FIELD||"upload",W=parseInt(process.env.API_UPLOAD_SIZE||"2"),X=process.env.API_UPLOAD_TEMP||"./temp",V=e.toBool(process.env.API_WEBSOCKET_START||"false"),J={type:r.UUID,defaultValue:r.UUIDV4,allowNull:!1,primaryKey:!0},Z=(()=>{switch(N){case"mariadb":return new r.Sequelize(x,q,D,{host:E,port:R,dialect:"mariadb",logging:j,define:{timestamps:!1}});case"mysql":return new r.Sequelize(x,q,D,{host:E,port:R,dialect:"mysql",logging:j,define:{timestamps:!1}});case"postgres":return new r.Sequelize(x,q,D,{host:E,port:R,dialect:"postgres",logging:j,define:{timestamps:!1}})}throw new Error("No database selected")})();class $ extends r.Model{}$.init({login:r.DataTypes.BIGINT,logout:r.DataTypes.BIGINT,secret:r.DataTypes.STRING,timestamp:r.DataTypes.BIGINT,useragent:r.DataTypes.STRING},{sequelize:Z,modelName:"auth"});class Q extends r.Model{}Q.init({name:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:Z,modelName:"group"});class ee extends r.Model{}ee.init({name:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:Z,modelName:"route"});class te extends r.Model{}te.init({},{sequelize:Z,modelName:"groups_routes"}),te.removeAttribute("id");class re extends r.Model{}re.init({name:r.DataTypes.STRING,email:r.DataTypes.STRING,username:r.DataTypes.STRING,password:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:Z,modelName:"user"});class se extends r.Model{}se.init({},{sequelize:Z,modelName:"users_groups"}),se.removeAttribute("id");class oe extends r.Model{}oe.init({key:r.DataTypes.STRING,value:r.DataTypes.STRING},{sequelize:Z,modelName:"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),oe.removeAttribute("id");class ie extends r.Model{}var ne;ie.init({type:r.DataTypes.STRING,source:r.DataTypes.STRING,message:r.DataTypes.TEXT},{sequelize:Z,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),re.hasMany($),$.belongsTo(re),Q.hasMany(te),te.belongsTo(Q),ee.hasMany(te),te.belongsTo(ee),re.hasMany(se),se.belongsTo(re),Q.hasMany(se),se.belongsTo(Q),function(e){e.ERROR="[31m",e.INFO="[36m",e.NONE="[37m",e.SUCCESS="[32m",e.WARNING="[33m"}(ne||(ne={}));class ae{static write(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.NONE,"",e,t,r)}))}static error(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.ERROR,"error",e,t,r)}))}static info(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.INFO,"info",e,t,r)}))}static success(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.ERROR,"success",e,t,r)}))}static warning(e,t,r){return b(this,void 0,void 0,(function*(){yield ae.writeRaw(ne.WARNING,"warning",e,t,r)}))}static writeConsole(t,r,s){const o=e.dateFormat(new Date,"%H:%M:%S");console.log(">",t,r+" ".repeat(10-r.length),"[37m","|",o,"|",s)}static writeRaw(e,t,r,s,o){return b(this,void 0,void 0,(function*(){o&&ae.writeConsole(e,t,r),yield ie.create({type:t,source:s,message:r}).catch((()=>null))}))}}class de{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t,r){return e.status(400).json({message:t,details:r})}static unauthorized(e,t){return e.status(401).json({message:t})}}class ue{constructor(e){this.model=e}add(){return(e,t)=>b(this,void 0,void 0,(function*(){const r=yield this.model.create(e.body).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)}));return r?de.data(t,{id:r.id}):de.error(t,"Internal Server Error")}))}all(t,s){return(o,i)=>b(this,void 0,void 0,(function*(){var n,a,d,u,l;const c=Object.assign({},t||{});c.where=Object.assign({},c.where||{});const p=null===(n=o.query.limit)||void 0===n?void 0:n.toString();p&&(c.limit=parseInt(p));const f=null===(a=o.query.offset)||void 0===a?void 0:a.toString();f&&(c.offset=parseInt(f));const v=Object.keys(this.model.getAttributes()),m=[],g=null===(d=o.query.asc)||void 0===d?void 0:d.toString();g&&g.length&&g.split(",").forEach((e=>{v.indexOf(e)>=0&&m.push([e,"ASC"])}));const y=null===(u=o.query.desc)||void 0===u?void 0:u.toString();y&&y.length&&y.split(",").forEach((e=>{v.indexOf(e)>=0&&m.push([e,"DESC"])})),m.length&&(c.order=m);const h=[],I=e.isArray(c.attributes)?c.attributes:v,T=null===(l=o.query.search)||void 0===l?void 0:l.toString();I.forEach((t=>{var s;if(e.isString(t)&&(T&&T.length&&h.push({[t]:{[r.Op.like]:`%${T}%`}}),"search_"+t in o.query)){const e=null===(s=o.query["search_"+t])||void 0===s?void 0:s.toString();e&&e.length&&h.push({[t]:{[r.Op.like]:`%${e}%`}})}})),h.length&&(c.where=Object.assign(Object.assign({},c.where),{[r.Op.or]:[...h]}));const w=yield this.model.findAll(c).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)})),_=yield this.model.count(c).catch(e.noop);return w?de.data(i,{count:_,records:s?s(w):w}):de.error(i,"Internal Server Error")}))}del(){return(e,t)=>b(this,void 0,void 0,(function*(){const{id:r}=e.params;return(yield this.model.destroy({where:{id:r}}).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)})))?de.success(t,"OK"):de.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>b(this,void 0,void 0,(function*(){e||(e={});const o=Object.assign({},e);o.where=o.where?Object.assign({},o.where):{};const{id:i}=r.params,n=yield this.model.findByPk(i,o).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)}));return n?de.data(s,t?t(n):n.toJSON()):null===n?de.notfound(s,"Record not found"):de.error(s,"Internal Server Error")}))}set(){return(e,t)=>b(this,void 0,void 0,(function*(){const{id:r}=e.params,[s]=(yield this.model.update(e.body,{where:{id:r}}).catch((e=>{ae.error(e.message,"api.controller."+this.model.tableName,!0)})))||[];return s?de.success(t,"OK"):de.success(t,"Record not changed")}))}}class le{static all(e,t){return b(this,void 0,void 0,(function*(){return yield ee.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:te,required:!0,include:[{model:Q,required:!0,where:{state:!0},include:[{model:se,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{ae.error(e.message,"api.permission",!0)}))}))}static get(e){return b(this,void 0,void 0,(function*(){const t=yield le.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return b(this,void 0,void 0,(function*(){const r=yield le.all(e,{name:t});return r&&!!r.length}))}}const ce=e=>{if(d.existsSync(e))return d.readFileSync(e)},pe={http:ce(k),token:ce(z)},fe={http:ce(B),token:ce(G)};class ve{static sign(e){return fe.token?{token:l.sign(e,fe.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static verify(e){if(!pe.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:l.verify(e,pe.token)}}catch(e){return{error:"Invalid Token"}}}}const me=["id","name","email","username"],ge=(e,t,r)=>b(void 0,void 0,void 0,(function*(){const s=e.get(M)||"",{error:o,decode:i}=ve.verify(s);if(o)return de.error(t,o);if(i){const{id:s,secret:o}=i;if(s&&i){const i=yield re.findOne({where:{id:s,state:!0}}).catch((e=>{ae.error(e.message,"api.auth",!0)}));if(i){const s=yield $.findOne({where:{secret:o,userId:i.id}}).catch((e=>{ae.error(e.message,"api.auth",!0)}));if(s){const o=Date.now();if(o>s.timestamp)return de.error(t,"Expired token");if(!s.logout){s.timestamp=o+6e4*K;const t=e.get("User-Agent");return t&&(s.useragent=t),yield s.save(),e.auth=s,e.user=i,r()}}}return de.error(t,"Access denied")}}return de.error(t,"Invalid token")})),ye=e=>(t,r,s)=>b(void 0,void 0,void 0,(function*(){const o=t.user;return o?(yield le.is(o,e))?s():de.error(r,"Unauthorized access"):de.unauthorized(r,"Access denied")})),he=(t,r)=>{const s=e.uuidv4()+"."+r;return d.existsSync(f.join(t,s))?he(t,r):s},Ie=e=>{const t={abortEarly:!1,allowUnknown:!0,stripUnknown:!0};return(r,s,o)=>{const{error:i,value:n}=e.validate(r.body,t);if(i){const e=i.details.map((e=>e.message)).join(", "),t=[];return i.details.forEach((e=>{var r;t.push({key:(null===(r=e.context)||void 0===r?void 0:r.key)||"",type:e.type})})),de.validation(s,"Validation error: "+e,t)}return r.body=n,o()}},Te={username:P.default.string().min(5).required(),password:P.default.string().min(5).required()},we=Ie(P.default.object(Te)),_e=a.Router();_e.get("/",ge,((t,r)=>b(void 0,void 0,void 0,(function*(){const s=t.user;if(!s)return de.unauthorized(r,"Access denied");const o=yield le.all(s);if(o){const t=e.allowedObject(me,s.toJSON()),i=o.map((e=>e.name));return de.data(r,Object.assign(Object.assign({},t),{permissions:i}))}return de.error(r,"Internal Server Error")})))),_e.post("/login",we,((t,r)=>b(void 0,void 0,void 0,(function*(){const{username:s,password:o}=t.body;if(!s||!o)return de.error(r,"Invalid parameters");yield e.sleep(O);const i=yield re.findOne({where:{username:s}}).catch((e=>{ae.error(e.message,"api.controller."+re.tableName,!0)}));if(!i)return de.notfound(r,"Username not found");if(!i.state)return de.error(r,"Username is disabled");const n=u.SHA256(o).toString();if(i.password!=n)return de.error(r,"Invalid password");const a=i.id,d=e.uniqueID(),{error:l,token:c}=ve.sign({id:a,secret:d});if(l)return de.error(r,l);if(c){const e=Date.now(),s=e+6e4*K,o=t.get("User-Agent"),i=yield $.create({login:e,secret:d,timestamp:s,useragent:o,userId:a}).catch((e=>{ae.error(e.message,"api.controller."+$.tableName,!0)}));if(i)return de.data(r,{token:c})}return de.error(r,"Internal Server Error")})))),_e.get("/logout",ge,((e,t)=>b(void 0,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),de.success(t,"Disconcerted")):de.unauthorized(t,"Access denied")}))));const Ae=new ue(Q),Pe=new ue(te),Se=Ae.add(),be=Ae.all(),Oe=Ae.del(),xe=Ae.get(),Ee=Ae.set(),De={name:P.default.string().min(3).required(),description:P.default.string().allow(null,""),state:P.default.boolean().required()},Re=Ie(P.default.object(De)),Ne={routes:P.default.array().items(P.default.number())},qe=Ie(P.default.object(Ne)),je={name:P.default.string().min(3).empty(""),description:P.default.string().allow(null,""),state:P.default.boolean().empty("")},ke=Ie(P.default.object(je)),Be=a.Router();Be.use(ge),Be.get("/",ye("groups.read"),be),Be.post("/",ye("groups.write"),Re,Se),Be.route("/:id").get(ye("groups.read"),xe).put(ye("groups.write"),ke,Ee).delete(ye("groups.write"),Oe),Be.route("/:id/routes").get(ye("groups.read"),qe,((e,t)=>b(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return Pe.all({where:{groupId:r},include:[{model:ee,required:!0}]},(e=>e.map((e=>e.route))))(e,t)})))).put(ye("groups.write"),qe,((e,t)=>b(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,o=yield Q.findByPk(r,{attributes:["id"]}).catch((e=>{ae.error(e.message,"api.controller."+Q.tableName,!0)}));if(o){const e=o.id;if(yield te.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield ee.count({where:{id:s[r]}}),t&&(yield te.create({groupId:e,routeId:s[r]}))}return de.success(t,"OK")}return null===o?de.notfound(t,"Record not found"):de.error(t,"Internal Server Error")}))));const Ue=new ue(ie),He=a.Router();He.use(ge),He.get("/",ye("logs.read"),((e,t)=>b(void 0,void 0,void 0,(function*(){const{source:r,type:s}=e.query,o=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return Ue.all({where:o,order:[["created","DESC"]]})(e,t)}))));const Ce=new ue(ee),Le=Ce.add(),ze=Ce.all(),Ge=Ce.del(),Me=Ce.get(),Ke=Ce.set(),Fe={name:P.default.string().min(5).required(),description:P.default.string().allow(null,""),state:P.default.boolean().required()},Ye=Ie(P.default.object(Fe)),We={name:P.default.string().min(5).empty(""),description:P.default.string().allow(null,""),state:P.default.boolean().empty("")},Xe=Ie(P.default.object(We)),Ve=a.Router();Ve.use(ge),Ve.get("/",ye("routes.read"),ze),Ve.post("/",ye("routes.write"),Ye,Le),Ve.route("/:id").get(ye("routes.read"),Me).put(ye("routes.write"),Xe,Ke).delete(ye("routes.write"),Ge);const Je=new ue(re),Ze=new ue(se),$e=["id","name","email","username","description","state"],Qe={name:P.default.string().min(5).required(),email:P.default.string().email().required(),username:P.default.string().min(5).required(),password:P.default.string().min(5).required(),description:P.default.string().allow(null,""),state:P.default.boolean().required()},et=Ie(P.default.object(Qe)),tt={groups:P.default.array().items(P.default.number())},rt=Ie(P.default.object(tt)),st={name:P.default.string().min(5).empty(""),email:P.default.string().email().empty(""),username:P.default.string().min(5).empty(""),password:P.default.string().min(5).empty(""),description:P.default.string().allow(null,""),state:P.default.boolean().empty("")},ot=Ie(P.default.object(st)),it=a.Router();it.use(ge),it.get("/",ye("users.read"),((e,t)=>b(void 0,void 0,void 0,(function*(){return Je.all({attributes:$e})(e,t)})))),it.post("/",ye("users.write"),et,((e,t)=>b(void 0,void 0,void 0,(function*(){return e.body.password=u.SHA256(e.body.password).toString(),yield Je.add()(e,t)})))),it.route("/:id").get(ye("users.read"),((e,t)=>b(void 0,void 0,void 0,(function*(){return Je.get({attributes:$e})(e,t)})))).put(ye("users.write"),ot,((e,t)=>b(void 0,void 0,void 0,(function*(){return e.body.password&&(e.body.password=u.SHA256(e.body.password).toString()),Je.set()(e,t)})))).delete(ye("users.write"),((e,t)=>b(void 0,void 0,void 0,(function*(){const r=e.user;if(r){const{id:s}=e.params;if(r.id.toString()!=s)return Je.del()(e,t)}return de.error(t,"Internal Server Error")})))),it.route("/:id/groups").get(ye("users.read"),((e,t)=>b(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return Ze.all({where:{userId:r},include:[{model:Q,required:!0}]},(e=>e.map((e=>e.group))))(e,t)})))).put(ye("users.write"),rt,((e,t)=>b(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,o=yield re.findByPk(r,{attributes:["id"]}).catch((e=>{ae.error(e.message,"api.controller."+re.tableName,!0)}));if(o){if(yield se.destroy({where:{userId:o.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield Q.count({where:{id:s[t]}}),e&&(yield se.create({userId:o.id,groupId:s[t]}))}return de.success(t,"OK")}return de.notfound(t,"Record not found")}))));const nt=a.Router();let at;nt.use("/auth",_e),nt.use("/groups",Be),nt.use("/logs",He),nt.use("/routes",Ve),nt.use("/users",it);const dt=a.Router(),ut=()=>{var e;return at||(at=w.default(),(e=at).use(w.default.json()),e.use(((e,t,r,s)=>e?(ae.error(e.message,"api.express",!0),de.error(r,"Internal Server Error")):s())),e.use(w.default.urlencoded({extended:!0})),e.disable("x-powered-by"),C&&e.use(T.default()),e.use("/api",dt),e.use("/api",nt),e.all("/api/*",((e,t)=>de.notfound(t,"Invalid API"))),H&&(d.existsSync(H)&&e.use(w.default.static(H)),e.get("*",((e,t)=>{if(!d.existsSync(H))return de.notfound(t,'File "index.html" not found');t.sendFile(H+"/index.html")})))),at};let lt;const ct=()=>(lt||(lt=(e=>{if(!pe.http||!fe.http){const t=h.createServer(e);return t.listen(U,(()=>ae.info("Server started on port "+U,"api.server",!0))),t}const t=h.createServer(((e,t)=>{const r=80==U?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),r=I.createServer({key:fe.http,cert:pe.http},e);if(L)return new i.Server((e=>{e.once("data",(s=>{e.pause(),e.unshift(s),(22===s[0]?r:t).emit("connection",e),process.nextTick((()=>e.resume()))}))})).listen(U,(()=>ae.info("Server started on port "+U,"api.server",!0))),r;return 443==U&&t.listen(80,(()=>ae.info("Server started on port 80","api.server",!0))),r.listen(U,(()=>ae.info("Server started on port "+U,"api.server",!0))),r})(ut())),lt),pt=e=>{const t=new S.default.Server({server:e,verifyClient:ft});return t.on("connection",(e=>{e.on("message",(t=>b(void 0,void 0,void 0,(function*(){ve.verify(t.toString()),e.close()})))),setTimeout((()=>{e.close()}),2e3),e.on("close",(()=>{t.emit("close",e)}))})),t},ft=(e,t)=>t(V);exports.API_AUTH_SLEEP=O,exports.API_DB_DATABASE=x,exports.API_DB_HOST=E,exports.API_DB_LOG=j,exports.API_DB_PASSWORD=D,exports.API_DB_PORT=R,exports.API_DB_TYPE=N,exports.API_DB_USERNAME=q,exports.API_HTTP_CROSS=C,exports.API_HTTP_CRT=k,exports.API_HTTP_HYBRID=L,exports.API_HTTP_KEY=B,exports.API_HTTP_PORT=U,exports.API_HTTP_PUBLIC=H,exports.API_TOKEN_CRT=z,exports.API_TOKEN_HEADER=M,exports.API_TOKEN_KEY=G,exports.API_TOKEN_LIFETIME=K,exports.API_UPLOAD_COUNT=F,exports.API_UPLOAD_FIELD=Y,exports.API_UPLOAD_SIZE=W,exports.API_UPLOAD_TEMP=X,exports.API_WEBSOCKET_START=V,exports.Auth=$,exports.Config=class{static all(){return b(this,void 0,void 0,(function*(){const e=yield oe.findAll().catch((e=>{ae.error(e.message,"api.config",!0)})),t={};return e&&e.forEach((e=>{t[e.key]=e.value})),t}))}static del(e){return b(this,void 0,void 0,(function*(){return((yield oe.destroy({where:{key:e}}).catch((e=>{ae.error(e.message,"api.config",!0)})))||0)>0}))}static get(e){return b(this,void 0,void 0,(function*(){const t=yield oe.findOne({where:{key:e}}).catch((e=>{ae.error(e.message,"api.config",!0)}));return t&&t.value||""}))}static set(e,t){return b(this,void 0,void 0,(function*(){const[r]=(yield oe.findOrCreate({where:{key:e}}).catch((e=>{ae.error(e.message,"api.config",!0)})))||[];r&&(r.value=t,yield r.save().catch((e=>{ae.error(e.message,"api.config",!0)})))}))}},exports.Configs=oe,exports.Controller=ue,exports.Group=Q,exports.GroupRoute=te,exports.Log=ae,exports.Logs=ie,exports.Permission=le,exports.Responses=de,exports.Route=ee,exports.Token=ve,exports.User=re,exports.UserGroup=se,exports.auth=ge,exports.crt=pe,exports.initialize=()=>b(void 0,void 0,void 0,(function*(){yield Z.sync();const e=ct();V&&pt(e)})),exports.key=fe,exports.permission=ye,exports.router=dt,exports.sequelize=Z,exports.startSocket=pt,exports.upload=e=>{const t=(null==e?void 0:e.path)||X,r=A.default.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>b(void 0,void 0,void 0,(function*(){return s(null,he(t,_.default.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||W),o=A.default({storage:r,fileFilter(t,r,s){var o;return b(this,void 0,void 0,(function*(){const t=null===(o=null==e?void 0:e.types)||void 0===o?void 0:o.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),i=(null==e?void 0:e.count)||F,n=(null==e?void 0:e.field)||Y,a=o.array(n,i);return(e,t,r)=>{a(e,t,(function(e){return e?de.error(t,e.message):r()}))}},exports.useExpress=ut,exports.uuid=J,exports.validation=Ie;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrewcaires/api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Simple api for small applications using express, jsonwebtoken, sequelize and websocket",
|
|
5
5
|
"main": "dist/index.umd.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@andrewcaires/utils.js": "^0.1.6",
|
|
39
39
|
"cors": "^2.8.5",
|
|
40
40
|
"crypto-js": "^4.1.1",
|
|
41
|
-
"dotenv": "^16.0.
|
|
41
|
+
"dotenv": "^16.0.2",
|
|
42
42
|
"express": "^4.18.1",
|
|
43
43
|
"fs": "^0.0.1-security",
|
|
44
44
|
"joi": "^17.6.0",
|
|
@@ -47,30 +47,30 @@
|
|
|
47
47
|
"mime-types": "^2.1.35",
|
|
48
48
|
"multer": "^1.4.5-lts.1",
|
|
49
49
|
"mysql2": "^2.3.3",
|
|
50
|
-
"pg": "^8.
|
|
50
|
+
"pg": "^8.8.0",
|
|
51
51
|
"pg-hstore": "^2.3.4",
|
|
52
52
|
"sequelize": "^6.21.4",
|
|
53
53
|
"ws": "^8.8.1"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@rollup/plugin-commonjs": "^22.0.2",
|
|
57
|
-
"@rollup/plugin-typescript": "^8.
|
|
57
|
+
"@rollup/plugin-typescript": "^8.4.0",
|
|
58
58
|
"@types/cors": "^2.8.12",
|
|
59
59
|
"@types/crypto-js": "^4.1.1",
|
|
60
60
|
"@types/express": "^4.17.13",
|
|
61
|
-
"@types/jsonwebtoken": "^8.5.
|
|
61
|
+
"@types/jsonwebtoken": "^8.5.9",
|
|
62
62
|
"@types/mime-types": "^2.1.1",
|
|
63
63
|
"@types/multer": "^1.4.7",
|
|
64
|
-
"@types/node": "^18.7.
|
|
64
|
+
"@types/node": "^18.7.14",
|
|
65
65
|
"@types/ws": "^8.5.3",
|
|
66
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
67
|
-
"@typescript-eslint/parser": "^5.
|
|
68
|
-
"eslint": "^8.
|
|
69
|
-
"rollup": "^2.
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
|
67
|
+
"@typescript-eslint/parser": "^5.36.1",
|
|
68
|
+
"eslint": "^8.23.0",
|
|
69
|
+
"rollup": "^2.79.0",
|
|
70
70
|
"rollup-plugin-dts": "^4.2.2",
|
|
71
71
|
"rollup-plugin-terser": "^7.0.2",
|
|
72
72
|
"ts-node": "^10.9.1",
|
|
73
73
|
"ts-node-dev": "^2.0.0",
|
|
74
|
-
"typescript": "^4.
|
|
74
|
+
"typescript": "^4.8.2"
|
|
75
75
|
}
|
|
76
76
|
}
|