@andrewcaires/api 1.0.11 → 2.0.0

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  [![npm](https://img.shields.io/npm/v/@andrewcaires/api?color=blue&logo=npm)](https://www.npmjs.com/package/@andrewcaires/api)
2
2
  [![downloads](https://img.shields.io/npm/dt/@andrewcaires/api?color=blue)](https://www.npmjs.com/package/@andrewcaires/api)
3
3
  [![size](https://img.shields.io/bundlephobia/min/@andrewcaires/api?color=blue)](https://www.npmjs.com/package/@andrewcaires/api)
4
- [![license](https://img.shields.io/github/license/andrewcaires/npm?color=blue)](https://github.com/andrewcaires/npm/blob/main/LICENSE)
4
+ [![license](https://img.shields.io/npm/l/@andrewcaires/api?color=blue)](https://www.npmjs.com/package/@andrewcaires/api)
5
5
 
6
6
  # API
7
7
 
@@ -14,17 +14,75 @@ The module is now available on npm! `npm i @andrewcaires/api`
14
14
  ## Example usage
15
15
 
16
16
  ```js
17
- import { initialize } from '@andrewcaires/api';
17
+ // .env
18
18
 
19
- initialize();
19
+ NODE_ENV=development
20
+
21
+ API_DB_TYPE=mariadb
22
+ API_DB_DATABASE=api
23
+ API_DB_HOST=localhost
24
+ API_DB_USERNAME=root
25
+ API_DB_PASSWORD=
26
+ API_DB_LOG=false
27
+ API_DB_PORT=3306
28
+
29
+ API_HTTP_PORT=3000
30
+ API_HTTP_PUBLIC=/public
31
+ API_HTTP_CROSS=true
32
+
33
+ API_HTTP_CRT=/ssl/http.crt
34
+ API_HTTP_KEY=/ssl/http.key
35
+
36
+ API_TOKEN_CRT=/ssh/token.crt
37
+ API_TOKEN_KEY=/ssh/token.key
38
+ API_TOKEN_LIFETIME=3000
39
+
40
+ API_WEBSOCKET_START=false
41
+ ```
42
+
43
+ ```js
44
+ // index.ts
45
+
46
+ import {
47
+
48
+ App,
49
+
50
+ AuthController,
51
+ GroupController,
52
+ GroupRouteController,
53
+ LogsController,
54
+ RouteController,
55
+ UserController,
56
+ UserGroupController,
57
+
58
+ } from "@andrewcaires/api";
59
+
60
+ (async () => {
61
+
62
+ const app = new App(
63
+ [
64
+
65
+ new AuthController("/auth"),
66
+ new GroupController("/groups"),
67
+ new GroupRouteController("/groups"),
68
+ new LogsController("/logs"),
69
+ new RouteController("/routes"),
70
+ new UserController("/users"),
71
+ new UserGroupController("/users"),
72
+
73
+ ]
74
+ );
75
+
76
+ await app.listen();
77
+
78
+ })();
20
79
  ```
21
80
 
22
81
  ### Links
23
82
 
24
- * [Docs](https://github.com/andrewcaires/npm/blob/main/api/README.md)
25
- * [GitHub](https://github.com/andrewcaires/npm/tree/main/api)
83
+ * [Docs](https://www.npmjs.com/package/@andrewcaires/api)
26
84
  * [npm](https://www.npmjs.com/package/@andrewcaires/api)
27
85
 
28
86
  ## License
29
87
 
30
- * [MIT](https://github.com/andrewcaires/npm/blob/main/LICENSE)
88
+ * [MIT](https://www.npmjs.com/package/@andrewcaires/api)
package/dist/index.cjs.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @andrewcaires/api v1.0.11
2
+ * @andrewcaires/api v2.0.0
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"),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="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(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),"","|",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(4).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().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().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().required(),description:P.default.string().allow(null,""),state:P.default.boolean().required()},Ye=Ie(P.default.object(Fe)),We={name:P.default.string().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().required(),email:P.default.string().email().required(),username:P.default.string().min(4).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().empty(""),email:P.default.string().email().empty(""),username:P.default.string().min(4).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;
7
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@andrewcaires/utils.js"),t=require("cors"),r=require("express"),s=require("fs"),i=require("http"),o=require("https"),n=require("net"),a=require("ws"),u=require("dotenv"),d=require("sequelize"),l=require("jsonwebtoken"),c=require("mime-types"),p=require("multer"),h=require("path"),m=require("crypto-js");function v(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function g(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 f=v(t),y=v(r),_=g(i),I=g(o),T=v(a),A=v(c),w=v(p);function S(e,t,r,s){return new(r||(r=Promise))((function(i,o){function n(e){try{u(s.next(e))}catch(e){o(e)}}function a(e){try{u(s.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,a)}u((s=s.apply(e,t||[])).next())}))}u.config();const b=parseInt(process.env.API_AUTH_SLEEP||"1000"),P=process.env.API_DB_DATABASE||"",x=process.env.API_DB_HOST||"127.0.0.1",O=process.env.API_DB_PASSWORD||"",E=parseInt(process.env.API_DB_PORT||"3306"),q=process.env.API_DB_TYPE||"",D=process.env.API_DB_USERNAME||"root",R=e.toBool(process.env.API_DB_LOG||"false"),N=process.env.API_HTTP_CRT||"",k=process.env.API_HTTP_KEY||"",B=parseInt(process.env.API_HTTP_PORT||"3000"),C=process.env.API_HTTP_PUBLIC||"",j=e.toBool(process.env.API_HTTP_CROSS||"false"),z=e.toBool(process.env.API_HTTP_HYBRID||"false"),G=process.env.API_TOKEN_CRT||"",V=process.env.API_TOKEN_KEY||"",M=process.env.API_TOKEN_HEADER||"authorization",U=parseInt(process.env.API_TOKEN_LIFETIME||"15"),H=parseInt(process.env.API_UPLOAD_COUNT||"1"),L=process.env.API_UPLOAD_FIELD||"upload",K=parseInt(process.env.API_UPLOAD_SIZE||"2"),F=process.env.API_UPLOAD_TEMP||"./temp",Y=e.toBool(process.env.API_WEBSOCKET_START||"false");class W{static connect(){const e={database:P,username:D,password:O,hostname:x,hostport:E};switch(q){case"mariadb":return W.mariadb(e);case"memory":default:return W.memory();case"mysql":return W.mysql(e);case"postgres":return W.postgres(e);case"sqlite":return W.sqlite(P)}}static mariadb(e){return new d.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mariadb",logging:R,define:{timestamps:!1}})}static memory(){return new d.Sequelize("sqlite::memory:",{logging:R,define:{timestamps:!1}})}static mysql(e){return new d.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mysql",logging:R,define:{timestamps:!1}})}static postgres(e){return new d.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"postgres",logging:R,define:{timestamps:!1}})}static sqlite(e){return new d.Sequelize({dialect:"sqlite",storage:e,logging:R,define:{timestamps:!1}})}}const X=W.connect();class J extends d.Model{}J.init({login:d.DataTypes.BIGINT,logout:d.DataTypes.BIGINT,secret:d.DataTypes.STRING,timestamp:d.DataTypes.BIGINT,useragent:d.DataTypes.STRING},{sequelize:X,modelName:"auth"});class Z extends d.Model{}Z.init({name:d.DataTypes.STRING,description:d.DataTypes.TEXT,state:d.DataTypes.BOOLEAN},{sequelize:X,modelName:"group"});class $ extends d.Model{}$.init({name:d.DataTypes.STRING,description:d.DataTypes.TEXT,state:d.DataTypes.BOOLEAN},{sequelize:X,modelName:"route"});class Q extends d.Model{}Q.init({},{sequelize:X,modelName:"groups_routes"}),Q.removeAttribute("id");class ee extends d.Model{}ee.init({name:d.DataTypes.STRING,email:d.DataTypes.STRING,username:d.DataTypes.STRING,password:d.DataTypes.STRING,description:d.DataTypes.TEXT,state:d.DataTypes.BOOLEAN},{sequelize:X,modelName:"user"});class te extends d.Model{}te.init({},{sequelize:X,modelName:"users_groups"}),te.removeAttribute("id");class re extends d.Model{}re.init({key:d.DataTypes.STRING,value:d.DataTypes.STRING},{sequelize:X,modelName:"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),re.removeAttribute("id");class se extends d.Model{}var ie;se.init({type:d.DataTypes.STRING,source:d.DataTypes.STRING,message:d.DataTypes.TEXT},{sequelize:X,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),ee.hasMany(J),J.belongsTo(ee),Z.hasMany(Q),Q.belongsTo(Z),$.hasMany(Q),Q.belongsTo($),ee.hasMany(te),te.belongsTo(ee),Z.hasMany(te),te.belongsTo(Z),function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(ie||(ie={}));class oe{static write(e,t,r){return S(this,void 0,void 0,(function*(){yield oe.writeRaw(ie.NONE,"",e,t,r)}))}static error(e,t,r){return S(this,void 0,void 0,(function*(){yield oe.writeRaw(ie.ERROR,"error",e,t,r)}))}static info(e,t,r){return S(this,void 0,void 0,(function*(){yield oe.writeRaw(ie.INFO,"info",e,t,r)}))}static success(e,t,r){return S(this,void 0,void 0,(function*(){yield oe.writeRaw(ie.ERROR,"success",e,t,r)}))}static warning(e,t,r){return S(this,void 0,void 0,(function*(){yield oe.writeRaw(ie.WARNING,"warning",e,t,r)}))}static writeConsole(t,r,s){const i=e.dateFormat(new Date,"%H:%M:%S");console.log(">",t,r+" ".repeat(10-r.length),"","|",i,"|",s)}static writeRaw(e,t,r,s,i){return S(this,void 0,void 0,(function*(){i&&oe.writeConsole(e,t,r),X&&(yield se.create({type:t,source:s,message:r}).catch((()=>null)))}))}}class ne{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){return e.status(400).json({message:t})}static unauthorized(e,t){return e.status(401).json({message:t})}}const ae=e=>s.existsSync(e)?s.readFileSync(e):void 0,ue={http:ae(N),token:ae(G)},de={http:ae(k),token:ae(V)};class le{static sign(e){return de.token?{token:l.sign(e,de.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static user(e){return S(this,void 0,void 0,(function*(){const{error:t,decode:r}=le.verify(e);if(t)return{error:t};if(r){const{id:e,secret:t}=r;if(e&&r){const r=yield ee.findOne({where:{id:e,state:!0}}).catch((e=>{oe.error(e.message,"api.token",!0)}));if(r){const e=yield J.findOne({where:{secret:t,userId:r.id}}).catch((e=>{oe.error(e.message,"api.token",!0)}));if(e){const t=Date.now();if(t>e.timestamp)return{error:"Expired token"};if(e.timestamp=t+6e4*U,yield e.save(),!e.logout)return{auth:e,user:r}}}return{error:"Access denied"}}}return{error:"Invalid token"}}))}static verify(e){if(!ue.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:l.verify(e,ue.token)}}catch(e){return{error:"Invalid Token"}}}}class ce extends e.EventEmitter{constructor(e){super(),this.app=y.default(),this.router=r.Router(),this.middlewares(),this.controllers(e)}controllers(e){e.forEach((e=>{e.intialize(),this.router.use(e.path(),e.router)}))}listen(){return S(this,void 0,void 0,(function*(){if(yield X.sync(),ue.http&&de.http||(this._server=_.createServer(this.app),this._server.listen(B,(()=>oe.info("Server started on port "+B,"api.server",!0)))),!this._server){const e=_.createServer(((e,t)=>{const r=80==B?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),t=I.createServer({key:de.http,cert:ue.http},this.app);if(z){new n.Server((r=>{r.once("data",(s=>{r.pause(),r.unshift(s),(22===s[0]?t:e).emit("connection",r),process.nextTick((()=>r.resume()))}))})).listen(B,(()=>oe.info("Server started on port "+B,"api.server",!0))),this._server=t}this._server||(443==B&&e.listen(80,(()=>oe.info("Server started on port 80","api.server",!0))),t.listen(B,(()=>oe.info("Server started on port "+B,"api.server",!0))),this._server=t)}Y&&this._server&&(this._webSocket=new T.default.Server({server:this._server,verifyClient:(e,t)=>t(Y)}),this._webSocket.on("connection",((t,r)=>S(this,void 0,void 0,(function*(){r.url||(r.url="");const s=r.url.length<=1?"":r.url.replace(/\//g,".");let i;t.on("message",(e=>S(this,void 0,void 0,(function*(){if(i)try{const o=JSON.parse(e);this.emit("ws.message"+s,{data:o,message:e,req:r,user:i,ws:t})}catch(o){this.emit("ws.message"+s,{message:e,req:r,user:i,ws:t})}else{const{user:o}=yield le.user(e.toString());o&&(i=o,this.emit("ws.connection"+s,{req:r,user:i,ws:t}))}i||t.close()})))),t.on("close",(()=>{i&&this.emit("ws.close"+s,{user:i,ws:t})})),yield e.sleep(2e3),i||t.close()})))))}))}middlewares(){this.app.use(r.json()),this.app.use(((e,t,r,s)=>e?(oe.error(e.message,"api.express",!0),ne.error(r,"Internal Server Error")):s())),this.app.use(r.urlencoded({extended:!0})),this.app.disable("x-powered-by"),j&&this.app.use(f.default()),this.app.use("/api",this.router),this.app.all("/api/*",((e,t)=>ne.notfound(t,"Invalid API"))),C&&(s.existsSync(C)&&this.app.use(y.default.static(C)),this.app.get("*",((e,t)=>{if(!s.existsSync(C))return ne.notfound(t,'File "index.html" not found');t.sendFile(C+"/index.html")})))}server(){return this._server}websocket(){return this._webSocket}}class pe{static all(e,t){return S(this,void 0,void 0,(function*(){return yield $.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:Q,required:!0,include:[{model:Z,required:!0,where:{state:!0},include:[{model:te,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{oe.error(e.message,"api.permission",!0)}))}))}static get(e){return S(this,void 0,void 0,(function*(){const t=yield pe.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return S(this,void 0,void 0,(function*(){const r=yield pe.all(e,{name:t});return r&&!!r.length}))}}const he=(t,r)=>{const i=e.uuidv4()+"."+r;return s.existsSync(h.join(t,i))?he(t,r):i};class me{constructor(e){this.router=r.Router(),this._path=e}auth(e,t,r){return S(this,void 0,void 0,(function*(){const s=e.get(M)||"",{auth:i,error:o,user:n}=yield le.user(s);if(o)return ne.error(t,o);if(i&&n){const t=e.get("User-Agent");return t&&(i.useragent=t),yield i.save(),e.auth=i,e.user=n,r()}return ne.error(t,"Internal Server Error")}))}intialize(){}name(){return"api"}path(){return this._path}permission(e){return(t,r,s)=>S(this,void 0,void 0,(function*(){const i=t.user;return i?(yield pe.is(i,e))?s():ne.error(r,"Unauthorized access"):ne.unauthorized(r,"Access denied")}))}read(e=""){return this.permission((e||this.name())+".read")}upload(e){const t=(null==e?void 0:e.path)||F,r=w.default.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>S(this,void 0,void 0,(function*(){return s(null,he(t,A.default.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||K),i=w.default({storage:r,fileFilter(t,r,s){var i;return S(this,void 0,void 0,(function*(){const t=null===(i=null==e?void 0:e.types)||void 0===i?void 0:i.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),o=(null==e?void 0:e.count)||H,n=(null==e?void 0:e.field)||L,a=i.array(n,o);return(e,t,r)=>{a(e,t,(function(e){return e?ne.error(t,e.message):r()}))}}validation(t){return(r,s,i)=>{const{error:o,value:n}=e.Validation.object(t).validate(r.body);return o?ne.validation(s,o):(r.body=n,i())}}write(e=""){return this.permission((e||this.name())+".write")}}class ve extends me{add(){return(e,t)=>S(this,void 0,void 0,(function*(){if(!this._model)return ne.error(t,"Internal Server Error");const r=yield this._model.create(e.body).catch((e=>{oe.error(e.message,"api.controller."+this.name(),!0)}));return r?ne.data(t,{id:r.id}):ne.error(t,"Internal Server Error")}))}all(t,r){return(s,i)=>S(this,void 0,void 0,(function*(){var o,n,a,u,l;if(!this._model)return ne.error(i,"Internal Server Error");const c=Object.assign({},t||{});c.where=Object.assign({},c.where||{});const p=null===(o=s.query.limit)||void 0===o?void 0:o.toString();p&&(c.limit=parseInt(p));const h=null===(n=s.query.offset)||void 0===n?void 0:n.toString();h&&(c.offset=parseInt(h));const m=Object.keys(this._model.getAttributes()),v=[],g=null===(a=s.query.asc)||void 0===a?void 0:a.toString();g&&g.length&&g.split(",").forEach((e=>{m.indexOf(e)>=0&&v.push([e,"ASC"])}));const f=null===(u=s.query.desc)||void 0===u?void 0:u.toString();f&&f.length&&f.split(",").forEach((e=>{m.indexOf(e)>=0&&v.push([e,"DESC"])})),v.length&&(c.order=v);const y=[],_=e.isArray(c.attributes)?c.attributes:m,I=null===(l=s.query.search)||void 0===l?void 0:l.toString();_.forEach((t=>{var r;if(e.isString(t)&&(I&&I.length&&y.push({[t]:{[d.Op.like]:`%${I}%`}}),"search_"+t in s.query)){const e=null===(r=s.query["search_"+t])||void 0===r?void 0:r.toString();e&&e.length&&y.push({[t]:{[d.Op.like]:`%${e}%`}})}})),y.length&&(c.where=Object.assign(Object.assign({},c.where),{[d.Op.or]:[...y]}));const T=yield this._model.findAll(c).catch((e=>{oe.error(e.message,"api.controller."+this.name(),!0)})),A=yield this._model.count(c).catch(e.noop);return T?ne.data(i,{count:A,records:r?r(T):T}):ne.error(i,"Internal Server Error")}))}del(){return(e,t)=>S(this,void 0,void 0,(function*(){if(!this._model)return ne.error(t,"Internal Server Error");const{id:r}=e.params;return(yield this._model.destroy({where:{id:r}}).catch((e=>{oe.error(e.message,"api.controller."+this.name(),!0)})))?ne.success(t,"OK"):ne.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>S(this,void 0,void 0,(function*(){if(!this._model)return ne.error(s,"Internal Server Error");e||(e={});const i=Object.assign({},e);i.where=i.where?Object.assign({},i.where):{};const{id:o}=r.params,n=yield this._model.findByPk(o,i).catch((e=>{oe.error(e.message,"api.controller."+this.name(),!0)}));return n?ne.data(s,t?t(n):n.toJSON()):null===n?ne.notfound(s,"Record not found"):ne.error(s,"Internal Server Error")}))}name(){var e;return this._model?null===(e=this._model)||void 0===e?void 0:e.tableName:super.name()}set(){return(e,t)=>S(this,void 0,void 0,(function*(){if(!this._model)return ne.error(t,"Internal Server Error");const{id:r}=e.params,[s]=(yield this._model.update(e.body,{where:{id:r}}).catch((e=>{oe.error(e.message,"api.controller."+this.name(),!0)})))||[];return s?ne.success(t,"OK"):ne.success(t,"Record not changed")}))}getModel(){return this._model}setModel(e){this._model=e}}class ge extends ve{intialize(){const e=this.model();e&&this.setModel(e),this.router.use(this.auth),this.router.get("/",this.read(),this.all().bind(this)),this.router.post("/",this.write(),this.validation(this.create()),this.add().bind(this)),this.router.route("/:id").get(this.read(),this.get().bind(this)).put(this.write(),this.validation(this.update()),this.set().bind(this)).delete(this.write(),this.del().bind(this))}}exports.API_AUTH_SLEEP=b,exports.API_DB_DATABASE=P,exports.API_DB_HOST=x,exports.API_DB_LOG=R,exports.API_DB_PASSWORD=O,exports.API_DB_PORT=E,exports.API_DB_TYPE=q,exports.API_DB_USERNAME=D,exports.API_HTTP_CROSS=j,exports.API_HTTP_CRT=N,exports.API_HTTP_HYBRID=z,exports.API_HTTP_KEY=k,exports.API_HTTP_PORT=B,exports.API_HTTP_PUBLIC=C,exports.API_TOKEN_CRT=G,exports.API_TOKEN_HEADER=M,exports.API_TOKEN_KEY=V,exports.API_TOKEN_LIFETIME=U,exports.API_UPLOAD_COUNT=H,exports.API_UPLOAD_FIELD=L,exports.API_UPLOAD_SIZE=K,exports.API_UPLOAD_TEMP=F,exports.API_WEBSOCKET_START=Y,exports.App=ce,exports.Auth=J,exports.AuthController=class extends me{constructor(){super(...arguments),this.attributes=["id","name","email","username"],this.query={username:e.Validation.string().min(4).required(),password:e.Validation.string().min(5).required()}}intialize(){this.router.get("/",this.auth,this.user.bind(this)),this.router.post("/login",this.validation(this.query),this.login.bind(this)),this.router.get("/logout",this.auth,this.logout.bind(this))}login(t,r){return S(this,void 0,void 0,(function*(){yield e.sleep(b);const{username:s,password:i}=t.body,o=yield ee.findOne({where:{username:s}}).catch((e=>{oe.error(e.message,"api.controller."+this.name(),!0)}));if(!o)return ne.notfound(r,"Username not found");if(!o.state)return ne.error(r,"Username is disabled");const n=m.SHA256(i).toString();if(o.password!=n)return ne.error(r,"Invalid password");const a=o.id,u=e.uniqueID(),{error:d,token:l}=le.sign({id:a,secret:u});if(d)return ne.error(r,d);if(l){const e=Date.now(),s=e+6e4*U,i=t.get("User-Agent"),o=yield J.create({login:e,secret:u,timestamp:s,useragent:i,userId:a}).catch((e=>{oe.error(e.message,"api.controller."+this.name(),!0)}));if(o)return ne.data(r,{token:l})}return ne.error(r,"Internal Server Error")}))}logout(e,t){return S(this,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),ne.success(t,"Disconcerted")):ne.unauthorized(t,"Access denied")}))}user(t,r){return S(this,void 0,void 0,(function*(){const s=t.user;if(!s)return ne.unauthorized(r,"Access denied");const i=yield pe.all(s);if(i){const t=e.allowedObject(this.attributes,s.toJSON()),o=i.map((e=>e.name));return ne.data(r,Object.assign(Object.assign({},t),{permissions:o}))}return ne.error(r,"Internal Server Error")}))}},exports.Config=class{static all(){return S(this,void 0,void 0,(function*(){const e=yield re.findAll().catch((e=>{oe.error(e.message,"api.config",!0)})),t={};return e&&e.forEach((e=>{t[e.key]=e.value})),t}))}static del(e){return S(this,void 0,void 0,(function*(){return((yield re.destroy({where:{key:e}}).catch((e=>{oe.error(e.message,"api.config",!0)})))||0)>0}))}static get(e){return S(this,void 0,void 0,(function*(){const t=yield re.findOne({where:{key:e}}).catch((e=>{oe.error(e.message,"api.config",!0)}));return t&&t.value||""}))}static set(e,t){return S(this,void 0,void 0,(function*(){const[r]=(yield re.findOrCreate({where:{key:e}}).catch((e=>{oe.error(e.message,"api.config",!0)})))||[];r&&(r.value=t,yield r.save().catch((e=>{oe.error(e.message,"api.config",!0)})))}))}},exports.Configs=re,exports.Controller=me,exports.CrudController=ge,exports.Database=W,exports.Group=Z,exports.GroupController=class extends ge{create(){return{name:e.Validation.string().required(),description:e.Validation.string().empty(""),state:e.Validation.boolean().required()}}model(){return Z}update(){return{name:e.Validation.string().empty(),description:e.Validation.string().empty(),state:e.Validation.boolean().empty()}}},exports.GroupRoute=Q,exports.GroupRouteController=class extends ve{constructor(){super(...arguments),this.groups={groups:e.Validation.array().items(e.Validation.number())}}intialize(){this.setModel(Q),this.router.use(this.auth),this.router.route("/:id/groups").get(this.read("users"),this.groupRouteAll.bind(this)).put(this.write("users"),this.validation(this.groups),this.groupRouteSet.bind(this))}groupRouteAll(e,t){return S(this,void 0,void 0,(function*(){const{id:r}=e.params;return this.all({where:{groupId:r},include:[{model:$,required:!0}]},(e=>e.map((e=>e.route))))(e,t)}))}groupRouteSet(e,t){return S(this,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,i=yield Z.findByPk(r,{attributes:["id"]}).catch((e=>{oe.error(e.message,"api.controller."+this.name(),!0)}));if(i){const e=i.id;if(yield Q.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield $.count({where:{id:s[r]}}),t&&(yield Q.create({groupId:e,routeId:s[r]}))}return ne.success(t,"OK")}return null===i?ne.notfound(t,"Record not found"):ne.error(t,"Internal Server Error")}))}},exports.Log=oe,exports.Logs=se,exports.LogsController=class extends ve{intialize(){this.setModel(se),this.router.use(this.auth),this.router.get("/",this.read("logs"),this.logsAll.bind(this))}logsAll(e,t){return S(this,void 0,void 0,(function*(){const{source:r,type:s}=e.query,i=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return this.all({where:i,order:[["created","DESC"]]})(e,t)}))}},exports.ModelController=ve,exports.Permission=pe,exports.Responses=ne,exports.Route=$,exports.RouteController=class extends ge{create(){return{name:e.Validation.string().required(),description:e.Validation.string().empty(""),state:e.Validation.boolean().required()}}model(){return $}update(){return{name:e.Validation.string().empty(),description:e.Validation.string().empty(),state:e.Validation.boolean().empty()}}},exports.Token=le,exports.User=ee,exports.UserController=class extends ve{constructor(){super(...arguments),this.attributes=["id","name","email","username","description","state"],this.create={name:e.Validation.string().required(),email:e.Validation.string().email().required(),username:e.Validation.string().min(4).required(),password:e.Validation.string().min(5).required(),description:e.Validation.string().required(),state:e.Validation.boolean().required()},this.update={name:e.Validation.string().empty(),email:e.Validation.string().email().empty(),username:e.Validation.string().min(4).empty(),password:e.Validation.string().min(5).empty(),description:e.Validation.string().empty(),state:e.Validation.boolean().empty()}}intialize(){this.setModel(ee),this.router.use(this.auth),this.router.get("/",this.read(),this.userAll.bind(this)),this.router.post("/",this.write(),this.validation(this.create),this.userAdd.bind(this)),this.router.route("/:id").get(this.read(),this.userGet.bind(this)).put(this.write(),this.validation(this.update),this.userSet.bind(this)).delete(this.write(),this.userDel.bind(this))}userAdd(e,t){return S(this,void 0,void 0,(function*(){return e.body.password=m.SHA256(e.body.password).toString(),yield this.add()(e,t)}))}userAll(e,t){return S(this,void 0,void 0,(function*(){return this.all({attributes:this.attributes})(e,t)}))}userDel(e,t){return S(this,void 0,void 0,(function*(){const r=e.user;if(r){const{id:s}=e.params;if(r.id.toString()!=s)return this.del()(e,t)}return ne.error(t,"Internal Server Error")}))}userGet(e,t){return S(this,void 0,void 0,(function*(){return this.get({attributes:this.attributes})(e,t)}))}userSet(e,t){return S(this,void 0,void 0,(function*(){return e.body.password&&(e.body.password=m.SHA256(e.body.password).toString()),this.set()(e,t)}))}},exports.UserGroup=te,exports.UserGroupController=class extends ve{constructor(){super(...arguments),this.groups={groups:e.Validation.array(e.Validation.number())}}intialize(){this.setModel(te),this.router.use(this.auth),this.router.route("/:id/groups").get(this.read("groups"),this.userGroupsAll.bind(this)).put(this.write("groups"),this.validation(this.groups),this.userGroupsSet.bind(this))}userGroupsAll(e,t){return S(this,void 0,void 0,(function*(){const{id:r}=e.params;return this.all({where:{userId:r},include:[{model:Z,required:!0}]},(e=>e.map((e=>e.group))))(e,t)}))}userGroupsSet(e,t){return S(this,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,i=yield ee.findByPk(r,{attributes:["id"]}).catch((e=>{oe.error(e.message,"api.controller."+this.name(),!0)}));if(i){if(yield te.destroy({where:{userId:i.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield Z.count({where:{id:s[t]}}),e&&(yield te.create({userId:i.id,groupId:s[t]}))}return ne.success(t,"OK")}return ne.notfound(t,"Record not found")}))}},exports.crt=ue,exports.key=de,exports.sequelize=X;
package/dist/index.d.ts CHANGED
@@ -1,45 +1,18 @@
1
1
  /*!
2
- * @andrewcaires/api v1.0.11
2
+ * @andrewcaires/api v2.0.0
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 * as _sequelize from 'sequelize';
8
- import { Model, Sequelize, ModelStatic, FindOptions, Attributes } from 'sequelize';
9
7
  import * as express_serve_static_core from 'express-serve-static-core';
10
- import { Express, Request, Response, NextFunction } from 'express';
11
- import { ObjectSchema } from 'joi';
12
- import { TypeObjectString, TypeObject } from '@andrewcaires/utils.js';
13
- import { WhereOptions } from 'sequelize/types';
8
+ import { TypeObject, ValidationBase, EventEmitter, TypeObjectString } from '@andrewcaires/utils.js';
14
9
  import * as http from 'http';
15
10
  import * as https from 'https';
16
11
  import WebSocket from 'ws';
17
-
18
- declare const initialize: () => Promise<void>;
19
-
20
- declare const API_AUTH_SLEEP: number;
21
- declare const API_DB_DATABASE: string;
22
- declare const API_DB_HOST: string;
23
- declare const API_DB_PASSWORD: string;
24
- declare const API_DB_PORT: number;
25
- declare const API_DB_TYPE: string;
26
- declare const API_DB_USERNAME: string;
27
- declare const API_DB_LOG: boolean;
28
- declare const API_HTTP_CRT: string;
29
- declare const API_HTTP_KEY: string;
30
- declare const API_HTTP_PORT: number;
31
- declare const API_HTTP_PUBLIC: string;
32
- declare const API_HTTP_CROSS: boolean;
33
- declare const API_HTTP_HYBRID: boolean;
34
- declare const API_TOKEN_CRT: string;
35
- declare const API_TOKEN_KEY: string;
36
- declare const API_TOKEN_HEADER: string;
37
- declare const API_TOKEN_LIFETIME: number;
38
- declare const API_UPLOAD_COUNT: number;
39
- declare const API_UPLOAD_FIELD: string;
40
- declare const API_UPLOAD_SIZE: number;
41
- declare const API_UPLOAD_TEMP: string;
42
- declare const API_WEBSOCKET_START: boolean;
12
+ import * as qs from 'qs';
13
+ import { Request, Response, NextFunction } from 'express';
14
+ import { Model, FindOptions, Attributes, ModelStatic, Sequelize } from 'sequelize';
15
+ import { WhereOptions } from 'sequelize/types';
43
16
 
44
17
  declare class Route extends Model {
45
18
  id: number;
@@ -104,9 +77,6 @@ declare class Logs extends Model {
104
77
  message: string;
105
78
  }
106
79
 
107
- declare const router: express_serve_static_core.Router;
108
- declare const useExpress: () => Express;
109
-
110
80
  declare global {
111
81
  namespace Express {
112
82
  interface Request {
@@ -115,10 +85,6 @@ declare global {
115
85
  }
116
86
  }
117
87
  }
118
- declare const auth: (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
119
-
120
- declare const permission: (name: string) => (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
121
-
122
88
  interface UploadOptions {
123
89
  count?: number;
124
90
  field?: string;
@@ -126,26 +92,33 @@ interface UploadOptions {
126
92
  size?: number;
127
93
  types?: string[];
128
94
  }
129
- declare const upload: (options?: UploadOptions) => (req: Request, res: Response, next: NextFunction) => void;
130
-
131
- declare const validation: (schema: ObjectSchema) => (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
132
-
133
- declare const uuid: {
134
- type: _sequelize.AbstractDataTypeConstructor;
135
- defaultValue: _sequelize.AbstractDataTypeConstructor;
136
- allowNull: boolean;
137
- primaryKey: boolean;
138
- };
139
- declare const sequelize: Sequelize;
95
+ declare abstract class Controller {
96
+ private _path;
97
+ readonly router: express_serve_static_core.Router;
98
+ constructor(path: string);
99
+ protected auth(req: Request, res: Response, next: NextFunction): Promise<void | Response<any, Record<string, any>>>;
100
+ intialize(): void;
101
+ protected name(): string;
102
+ path(): string;
103
+ protected permission(name: string): (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
104
+ protected read(name?: string): (req: Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
105
+ protected upload(options: UploadOptions): (req: Request, res: Response, next: NextFunction) => void;
106
+ protected validation(options: TypeObject<ValidationBase>): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
107
+ protected write(name?: string): (req: Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
108
+ }
140
109
 
141
- declare const crt: {
142
- http: Buffer | undefined;
143
- token: Buffer | undefined;
144
- };
145
- declare const key: {
146
- http: Buffer | undefined;
147
- token: Buffer | undefined;
148
- };
110
+ declare class App extends EventEmitter {
111
+ private _server?;
112
+ private _webSocket?;
113
+ readonly app: express_serve_static_core.Express;
114
+ readonly router: express_serve_static_core.Router;
115
+ constructor(controllers: Array<Controller>);
116
+ private controllers;
117
+ listen(): Promise<void>;
118
+ private middlewares;
119
+ server(): http.Server | https.Server | undefined;
120
+ websocket(): WebSocket.Server | undefined;
121
+ }
149
122
 
150
123
  declare class Config {
151
124
  static all(): Promise<TypeObjectString>;
@@ -154,18 +127,120 @@ declare class Config {
154
127
  static set(key: string, value: string): Promise<void>;
155
128
  }
156
129
 
130
+ declare const API_AUTH_SLEEP: number;
131
+ declare const API_DB_DATABASE: string;
132
+ declare const API_DB_HOST: string;
133
+ declare const API_DB_PASSWORD: string;
134
+ declare const API_DB_PORT: number;
135
+ declare const API_DB_TYPE: string;
136
+ declare const API_DB_USERNAME: string;
137
+ declare const API_DB_LOG: boolean;
138
+ declare const API_HTTP_CRT: string;
139
+ declare const API_HTTP_KEY: string;
140
+ declare const API_HTTP_PORT: number;
141
+ declare const API_HTTP_PUBLIC: string;
142
+ declare const API_HTTP_CROSS: boolean;
143
+ declare const API_HTTP_HYBRID: boolean;
144
+ declare const API_TOKEN_CRT: string;
145
+ declare const API_TOKEN_KEY: string;
146
+ declare const API_TOKEN_HEADER: string;
147
+ declare const API_TOKEN_LIFETIME: number;
148
+ declare const API_UPLOAD_COUNT: number;
149
+ declare const API_UPLOAD_FIELD: string;
150
+ declare const API_UPLOAD_SIZE: number;
151
+ declare const API_UPLOAD_TEMP: string;
152
+ declare const API_WEBSOCKET_START: boolean;
153
+
154
+ declare class AuthController extends Controller {
155
+ readonly attributes: string[];
156
+ private query;
157
+ intialize(): void;
158
+ protected login(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
159
+ protected logout(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
160
+ protected user(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
161
+ }
162
+
157
163
  declare type FnRecord<M> = (records: M) => any;
158
164
  declare type FnRecords<M> = (records: Array<M>) => Array<any>;
159
- declare class Controller<M extends Model<M>> {
160
- private model;
161
- constructor(model: ModelStatic<M>);
162
- add(): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
163
- all(options?: FindOptions<Attributes<M>>, fn?: FnRecords<M>): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
164
- del(): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
165
- get(options?: FindOptions<Attributes<M>>, fn?: FnRecord<M>): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
166
- set(): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
165
+ declare abstract class ModelController<M extends Model<M>> extends Controller {
166
+ private _model?;
167
+ protected add(): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
168
+ protected all(options?: FindOptions<Attributes<M>>, fn?: FnRecords<M>): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
169
+ protected del(): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
170
+ protected get(options?: FindOptions<Attributes<M>>, fn?: FnRecord<M>): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
171
+ protected name(): string;
172
+ protected set(): (req: Request, res: Response) => Promise<Response<any, Record<string, any>>>;
173
+ protected getModel(): ModelStatic<M> | undefined;
174
+ protected setModel(model: ModelStatic<M>): void;
167
175
  }
168
176
 
177
+ declare abstract class CrudController<M extends Model<M>> extends ModelController<M> {
178
+ protected abstract create(): TypeObject<ValidationBase>;
179
+ intialize(): void;
180
+ protected abstract model(): ModelStatic<M>;
181
+ protected abstract update(): TypeObject<ValidationBase>;
182
+ }
183
+
184
+ declare class GroupController extends CrudController<Group> {
185
+ protected create(): TypeObject<ValidationBase>;
186
+ protected model(): ModelStatic<Group>;
187
+ protected update(): TypeObject<ValidationBase>;
188
+ }
189
+
190
+ declare class GroupRouteController extends ModelController<GroupRoute> {
191
+ private groups;
192
+ intialize(): void;
193
+ protected groupRouteAll(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
194
+ protected groupRouteSet(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
195
+ }
196
+
197
+ declare class LogsController extends ModelController<Logs> {
198
+ intialize(): void;
199
+ protected logsAll(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
200
+ }
201
+
202
+ declare class RouteController extends CrudController<Route> {
203
+ protected create(): TypeObject<ValidationBase>;
204
+ protected model(): ModelStatic<Route>;
205
+ protected update(): TypeObject<ValidationBase>;
206
+ }
207
+
208
+ declare class UserController extends ModelController<User> {
209
+ private attributes;
210
+ private create;
211
+ private update;
212
+ intialize(): void;
213
+ protected userAdd(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
214
+ protected userAll(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
215
+ protected userDel(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
216
+ protected userGet(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
217
+ protected userSet(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
218
+ }
219
+
220
+ declare class UserGroupController extends ModelController<UserGroup> {
221
+ private groups;
222
+ intialize(): void;
223
+ protected userGroupsAll(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
224
+ protected userGroupsSet(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
225
+ }
226
+
227
+ interface DatabaseOptions {
228
+ database: string;
229
+ username: string;
230
+ password: string;
231
+ hostname: string;
232
+ hostport: number;
233
+ }
234
+ declare class Database {
235
+ static connect(): Sequelize;
236
+ static mariadb(options: DatabaseOptions): Sequelize;
237
+ static memory(): Sequelize;
238
+ static mysql(options: DatabaseOptions): Sequelize;
239
+ static postgres(options: DatabaseOptions): Sequelize;
240
+ static sqlite(database: string): Sequelize;
241
+ }
242
+ declare const sequelize: Sequelize;
243
+
169
244
  declare class Log {
170
245
  static write(message: string, source?: string, console?: boolean): Promise<void>;
171
246
  static error(message: string, source?: string, console?: boolean): Promise<void>;
@@ -188,23 +263,36 @@ declare class Responses {
188
263
  static error(res: Response, message: string): Response<any, Record<string, any>>;
189
264
  static list(res: Response, arr: Array<any>): Response<any, Record<string, any>>;
190
265
  static notfound(res: Response, message: string): Response<any, Record<string, any>>;
191
- static validation(res: Response, message: string, details: any): Response<any, Record<string, any>>;
266
+ static validation(res: Response, message: string): Response<any, Record<string, any>>;
192
267
  static unauthorized(res: Response, message: string): Response<any, Record<string, any>>;
193
268
  }
194
269
 
270
+ declare const crt: {
271
+ http: Buffer | undefined;
272
+ token: Buffer | undefined;
273
+ };
274
+ declare const key: {
275
+ http: Buffer | undefined;
276
+ token: Buffer | undefined;
277
+ };
278
+
195
279
  interface TokenSign {
196
280
  error?: string;
197
281
  token?: string;
198
282
  }
283
+ interface TokenUser {
284
+ auth?: Auth;
285
+ error?: string;
286
+ user?: User;
287
+ }
199
288
  interface TokenVerify {
200
289
  error?: string;
201
290
  decode?: TypeObject<string | number | boolean>;
202
291
  }
203
292
  declare class Token {
204
293
  static sign(payload: TypeObject<string | number>): TokenSign;
294
+ static user(token: string): Promise<TokenUser>;
205
295
  static verify(token: string): TokenVerify;
206
296
  }
207
297
 
208
- declare const startSocket: (server: http.Server | https.Server) => WebSocket.Server;
209
-
210
- export { API_AUTH_SLEEP, API_DB_DATABASE, API_DB_HOST, API_DB_LOG, API_DB_PASSWORD, API_DB_PORT, API_DB_TYPE, API_DB_USERNAME, API_HTTP_CROSS, API_HTTP_CRT, API_HTTP_HYBRID, API_HTTP_KEY, API_HTTP_PORT, API_HTTP_PUBLIC, API_TOKEN_CRT, API_TOKEN_HEADER, API_TOKEN_KEY, API_TOKEN_LIFETIME, API_UPLOAD_COUNT, API_UPLOAD_FIELD, API_UPLOAD_SIZE, API_UPLOAD_TEMP, API_WEBSOCKET_START, Auth, Config, Configs, Controller, Group, GroupRoute, Log, Logs, Permission, Responses, Route, Token, User, UserGroup, auth, crt, initialize, key, permission, router, sequelize, startSocket, upload, useExpress, uuid, validation };
298
+ export { API_AUTH_SLEEP, API_DB_DATABASE, API_DB_HOST, API_DB_LOG, API_DB_PASSWORD, API_DB_PORT, API_DB_TYPE, API_DB_USERNAME, API_HTTP_CROSS, API_HTTP_CRT, API_HTTP_HYBRID, API_HTTP_KEY, API_HTTP_PORT, API_HTTP_PUBLIC, API_TOKEN_CRT, API_TOKEN_HEADER, API_TOKEN_KEY, API_TOKEN_LIFETIME, API_UPLOAD_COUNT, API_UPLOAD_FIELD, API_UPLOAD_SIZE, API_UPLOAD_TEMP, API_WEBSOCKET_START, App, Auth, AuthController, Config, Configs, Controller, CrudController, Database, Group, GroupController, GroupRoute, GroupRouteController, Log, Logs, LogsController, ModelController, Permission, Responses, Route, RouteController, Token, User, UserController, UserGroup, UserGroupController, crt, key, sequelize };
package/dist/index.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @andrewcaires/api v1.0.11
2
+ * @andrewcaires/api v2.0.0
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="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(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),"","|",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(4).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().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().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().required(),description:R.string().allow(null,""),state:R.boolean().required()},et=Ee(R.object(Qe)),tt={name:R.string().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().required(),email:R.string().email().required(),username:R.string().min(4).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().empty(""),email:R.string().email().empty(""),username:R.string().min(4).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};
7
+ import{toBool as e,dateFormat as t,EventEmitter as r,sleep as s,Validation as i,uuidv4 as n,uniqueID as o,allowedObject as a,isArray as d,isString as u,noop as c}from"@andrewcaires/utils.js";import l from"cors";import h,{Router as p,json as m,urlencoded as v}from"express";import{existsSync as g,readFileSync as f}from"fs";import*as y from"http";import*as w from"https";import{Server as I}from"net";import b from"ws";import{config as S}from"dotenv";import{Sequelize as _,DataTypes as A,Model as T,Op as E}from"sequelize";import{sign as O,verify as R}from"jsonwebtoken";import q from"mime-types";import N from"multer";import{join as P}from"path";import{SHA256 as k}from"crypto-js";function x(e,t,r,s){return new(r||(r=Promise))((function(i,n){function o(e){try{d(s.next(e))}catch(e){n(e)}}function a(e){try{d(s.throw(e))}catch(e){n(e)}}function d(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,a)}d((s=s.apply(e,t||[])).next())}))}S();const z=parseInt(process.env.API_AUTH_SLEEP||"1000"),D=process.env.API_DB_DATABASE||"",G=process.env.API_DB_HOST||"127.0.0.1",j=process.env.API_DB_PASSWORD||"",B=parseInt(process.env.API_DB_PORT||"3306"),M=process.env.API_DB_TYPE||"",C=process.env.API_DB_USERNAME||"root",U=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"),F=process.env.API_HTTP_PUBLIC||"",W=e(process.env.API_HTTP_CROSS||"false"),X=e(process.env.API_HTTP_HYBRID||"false"),Y=process.env.API_TOKEN_CRT||"",J=process.env.API_TOKEN_KEY||"",$=process.env.API_TOKEN_HEADER||"authorization",Z=parseInt(process.env.API_TOKEN_LIFETIME||"15"),Q=parseInt(process.env.API_UPLOAD_COUNT||"1"),V=process.env.API_UPLOAD_FIELD||"upload",ee=parseInt(process.env.API_UPLOAD_SIZE||"2"),te=process.env.API_UPLOAD_TEMP||"./temp",re=e(process.env.API_WEBSOCKET_START||"false");class se{static connect(){const e={database:D,username:C,password:j,hostname:G,hostport:B};switch(M){case"mariadb":return se.mariadb(e);case"memory":default:return se.memory();case"mysql":return se.mysql(e);case"postgres":return se.postgres(e);case"sqlite":return se.sqlite(D)}}static mariadb(e){return new _(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mariadb",logging:U,define:{timestamps:!1}})}static memory(){return new _("sqlite::memory:",{logging:U,define:{timestamps:!1}})}static mysql(e){return new _(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mysql",logging:U,define:{timestamps:!1}})}static postgres(e){return new _(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"postgres",logging:U,define:{timestamps:!1}})}static sqlite(e){return new _({dialect:"sqlite",storage:e,logging:U,define:{timestamps:!1}})}}const ie=se.connect();class ne extends T{}ne.init({login:A.BIGINT,logout:A.BIGINT,secret:A.STRING,timestamp:A.BIGINT,useragent:A.STRING},{sequelize:ie,modelName:"auth"});class oe extends T{}oe.init({name:A.STRING,description:A.TEXT,state:A.BOOLEAN},{sequelize:ie,modelName:"group"});class ae extends T{}ae.init({name:A.STRING,description:A.TEXT,state:A.BOOLEAN},{sequelize:ie,modelName:"route"});class de extends T{}de.init({},{sequelize:ie,modelName:"groups_routes"}),de.removeAttribute("id");class ue extends T{}ue.init({name:A.STRING,email:A.STRING,username:A.STRING,password:A.STRING,description:A.TEXT,state:A.BOOLEAN},{sequelize:ie,modelName:"user"});class ce extends T{}ce.init({},{sequelize:ie,modelName:"users_groups"}),ce.removeAttribute("id");class le extends T{}le.init({key:A.STRING,value:A.STRING},{sequelize:ie,modelName:"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),le.removeAttribute("id");class he extends T{}var pe;he.init({type:A.STRING,source:A.STRING,message:A.TEXT},{sequelize:ie,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),ue.hasMany(ne),ne.belongsTo(ue),oe.hasMany(de),de.belongsTo(oe),ae.hasMany(de),de.belongsTo(ae),ue.hasMany(ce),ce.belongsTo(ue),oe.hasMany(ce),ce.belongsTo(oe),function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(pe||(pe={}));class me{static write(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.NONE,"",e,t,r)}))}static error(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.ERROR,"error",e,t,r)}))}static info(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.INFO,"info",e,t,r)}))}static success(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.ERROR,"success",e,t,r)}))}static warning(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.WARNING,"warning",e,t,r)}))}static writeConsole(e,r,s){const i=t(new Date,"%H:%M:%S");console.log(">",e,r+" ".repeat(10-r.length),"","|",i,"|",s)}static writeRaw(e,t,r,s,i){return x(this,void 0,void 0,(function*(){i&&me.writeConsole(e,t,r),ie&&(yield he.create({type:t,source:s,message:r}).catch((()=>null)))}))}}class ve{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){return e.status(400).json({message:t})}static unauthorized(e,t){return e.status(401).json({message:t})}}const ge=e=>g(e)?f(e):void 0,fe={http:ge(L),token:ge(Y)},ye={http:ge(H),token:ge(J)};class we{static sign(e){return ye.token?{token:O(e,ye.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static user(e){return x(this,void 0,void 0,(function*(){const{error:t,decode:r}=we.verify(e);if(t)return{error:t};if(r){const{id:e,secret:t}=r;if(e&&r){const r=yield ue.findOne({where:{id:e,state:!0}}).catch((e=>{me.error(e.message,"api.token",!0)}));if(r){const e=yield ne.findOne({where:{secret:t,userId:r.id}}).catch((e=>{me.error(e.message,"api.token",!0)}));if(e){const t=Date.now();if(t>e.timestamp)return{error:"Expired token"};if(e.timestamp=t+6e4*Z,yield e.save(),!e.logout)return{auth:e,user:r}}}return{error:"Access denied"}}}return{error:"Invalid token"}}))}static verify(e){if(!fe.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:R(e,fe.token)}}catch(e){return{error:"Invalid Token"}}}}class Ie extends r{constructor(e){super(),this.app=h(),this.router=p(),this.middlewares(),this.controllers(e)}controllers(e){e.forEach((e=>{e.intialize(),this.router.use(e.path(),e.router)}))}listen(){return x(this,void 0,void 0,(function*(){if(yield ie.sync(),fe.http&&ye.http||(this._server=y.createServer(this.app),this._server.listen(K,(()=>me.info("Server started on port "+K,"api.server",!0)))),!this._server){const e=y.createServer(((e,t)=>{const r=80==K?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),t=w.createServer({key:ye.http,cert:fe.http},this.app);if(X){new I((r=>{r.once("data",(s=>{r.pause(),r.unshift(s),(22===s[0]?t:e).emit("connection",r),process.nextTick((()=>r.resume()))}))})).listen(K,(()=>me.info("Server started on port "+K,"api.server",!0))),this._server=t}this._server||(443==K&&e.listen(80,(()=>me.info("Server started on port 80","api.server",!0))),t.listen(K,(()=>me.info("Server started on port "+K,"api.server",!0))),this._server=t)}re&&this._server&&(this._webSocket=new b.Server({server:this._server,verifyClient:(e,t)=>t(re)}),this._webSocket.on("connection",((e,t)=>x(this,void 0,void 0,(function*(){t.url||(t.url="");const r=t.url.length<=1?"":t.url.replace(/\//g,".");let i;e.on("message",(s=>x(this,void 0,void 0,(function*(){if(i)try{const n=JSON.parse(s);this.emit("ws.message"+r,{data:n,message:s,req:t,user:i,ws:e})}catch(n){this.emit("ws.message"+r,{message:s,req:t,user:i,ws:e})}else{const{user:n}=yield we.user(s.toString());n&&(i=n,this.emit("ws.connection"+r,{req:t,user:i,ws:e}))}i||e.close()})))),e.on("close",(()=>{i&&this.emit("ws.close"+r,{user:i,ws:e})})),yield s(2e3),i||e.close()})))))}))}middlewares(){this.app.use(m()),this.app.use(((e,t,r,s)=>e?(me.error(e.message,"api.express",!0),ve.error(r,"Internal Server Error")):s())),this.app.use(v({extended:!0})),this.app.disable("x-powered-by"),W&&this.app.use(l()),this.app.use("/api",this.router),this.app.all("/api/*",((e,t)=>ve.notfound(t,"Invalid API"))),F&&(g(F)&&this.app.use(h.static(F)),this.app.get("*",((e,t)=>{if(!g(F))return ve.notfound(t,'File "index.html" not found');t.sendFile(F+"/index.html")})))}server(){return this._server}websocket(){return this._webSocket}}class be{static all(){return x(this,void 0,void 0,(function*(){const e=yield le.findAll().catch((e=>{me.error(e.message,"api.config",!0)})),t={};return e&&e.forEach((e=>{t[e.key]=e.value})),t}))}static del(e){return x(this,void 0,void 0,(function*(){return((yield le.destroy({where:{key:e}}).catch((e=>{me.error(e.message,"api.config",!0)})))||0)>0}))}static get(e){return x(this,void 0,void 0,(function*(){const t=yield le.findOne({where:{key:e}}).catch((e=>{me.error(e.message,"api.config",!0)}));return t&&t.value||""}))}static set(e,t){return x(this,void 0,void 0,(function*(){const[r]=(yield le.findOrCreate({where:{key:e}}).catch((e=>{me.error(e.message,"api.config",!0)})))||[];r&&(r.value=t,yield r.save().catch((e=>{me.error(e.message,"api.config",!0)})))}))}}class Se{static all(e,t){return x(this,void 0,void 0,(function*(){return yield ae.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:de,required:!0,include:[{model:oe,required:!0,where:{state:!0},include:[{model:ce,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{me.error(e.message,"api.permission",!0)}))}))}static get(e){return x(this,void 0,void 0,(function*(){const t=yield Se.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return x(this,void 0,void 0,(function*(){const r=yield Se.all(e,{name:t});return r&&!!r.length}))}}const _e=(e,t)=>{const r=n()+"."+t;return g(P(e,r))?_e(e,t):r};class Ae{constructor(e){this.router=p(),this._path=e}auth(e,t,r){return x(this,void 0,void 0,(function*(){const s=e.get($)||"",{auth:i,error:n,user:o}=yield we.user(s);if(n)return ve.error(t,n);if(i&&o){const t=e.get("User-Agent");return t&&(i.useragent=t),yield i.save(),e.auth=i,e.user=o,r()}return ve.error(t,"Internal Server Error")}))}intialize(){}name(){return"api"}path(){return this._path}permission(e){return(t,r,s)=>x(this,void 0,void 0,(function*(){const i=t.user;return i?(yield Se.is(i,e))?s():ve.error(r,"Unauthorized access"):ve.unauthorized(r,"Access denied")}))}read(e=""){return this.permission((e||this.name())+".read")}upload(e){const t=(null==e?void 0:e.path)||te,r=N.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>x(this,void 0,void 0,(function*(){return s(null,_e(t,q.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||ee),i=N({storage:r,fileFilter(t,r,s){var i;return x(this,void 0,void 0,(function*(){const t=null===(i=null==e?void 0:e.types)||void 0===i?void 0:i.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),n=(null==e?void 0:e.count)||Q,o=(null==e?void 0:e.field)||V,a=i.array(o,n);return(e,t,r)=>{a(e,t,(function(e){return e?ve.error(t,e.message):r()}))}}validation(e){return(t,r,s)=>{const{error:n,value:o}=i.object(e).validate(t.body);return n?ve.validation(r,n):(t.body=o,s())}}write(e=""){return this.permission((e||this.name())+".write")}}class Te extends Ae{constructor(){super(...arguments),this.attributes=["id","name","email","username"],this.query={username:i.string().min(4).required(),password:i.string().min(5).required()}}intialize(){this.router.get("/",this.auth,this.user.bind(this)),this.router.post("/login",this.validation(this.query),this.login.bind(this)),this.router.get("/logout",this.auth,this.logout.bind(this))}login(e,t){return x(this,void 0,void 0,(function*(){yield s(z);const{username:r,password:i}=e.body,n=yield ue.findOne({where:{username:r}}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));if(!n)return ve.notfound(t,"Username not found");if(!n.state)return ve.error(t,"Username is disabled");const a=k(i).toString();if(n.password!=a)return ve.error(t,"Invalid password");const d=n.id,u=o(),{error:c,token:l}=we.sign({id:d,secret:u});if(c)return ve.error(t,c);if(l){const r=Date.now(),s=r+6e4*Z,i=e.get("User-Agent"),n=yield ne.create({login:r,secret:u,timestamp:s,useragent:i,userId:d}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));if(n)return ve.data(t,{token:l})}return ve.error(t,"Internal Server Error")}))}logout(e,t){return x(this,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),ve.success(t,"Disconcerted")):ve.unauthorized(t,"Access denied")}))}user(e,t){return x(this,void 0,void 0,(function*(){const r=e.user;if(!r)return ve.unauthorized(t,"Access denied");const s=yield Se.all(r);if(s){const e=a(this.attributes,r.toJSON()),i=s.map((e=>e.name));return ve.data(t,Object.assign(Object.assign({},e),{permissions:i}))}return ve.error(t,"Internal Server Error")}))}}class Ee extends Ae{add(){return(e,t)=>x(this,void 0,void 0,(function*(){if(!this._model)return ve.error(t,"Internal Server Error");const r=yield this._model.create(e.body).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));return r?ve.data(t,{id:r.id}):ve.error(t,"Internal Server Error")}))}all(e,t){return(r,s)=>x(this,void 0,void 0,(function*(){var i,n,o,a,l;if(!this._model)return ve.error(s,"Internal Server Error");const h=Object.assign({},e||{});h.where=Object.assign({},h.where||{});const p=null===(i=r.query.limit)||void 0===i?void 0:i.toString();p&&(h.limit=parseInt(p));const m=null===(n=r.query.offset)||void 0===n?void 0:n.toString();m&&(h.offset=parseInt(m));const v=Object.keys(this._model.getAttributes()),g=[],f=null===(o=r.query.asc)||void 0===o?void 0:o.toString();f&&f.length&&f.split(",").forEach((e=>{v.indexOf(e)>=0&&g.push([e,"ASC"])}));const y=null===(a=r.query.desc)||void 0===a?void 0:a.toString();y&&y.length&&y.split(",").forEach((e=>{v.indexOf(e)>=0&&g.push([e,"DESC"])})),g.length&&(h.order=g);const w=[],I=d(h.attributes)?h.attributes:v,b=null===(l=r.query.search)||void 0===l?void 0:l.toString();I.forEach((e=>{var t;if(u(e)&&(b&&b.length&&w.push({[e]:{[E.like]:`%${b}%`}}),"search_"+e in r.query)){const s=null===(t=r.query["search_"+e])||void 0===t?void 0:t.toString();s&&s.length&&w.push({[e]:{[E.like]:`%${s}%`}})}})),w.length&&(h.where=Object.assign(Object.assign({},h.where),{[E.or]:[...w]}));const S=yield this._model.findAll(h).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)})),_=yield this._model.count(h).catch(c);return S?ve.data(s,{count:_,records:t?t(S):S}):ve.error(s,"Internal Server Error")}))}del(){return(e,t)=>x(this,void 0,void 0,(function*(){if(!this._model)return ve.error(t,"Internal Server Error");const{id:r}=e.params;return(yield this._model.destroy({where:{id:r}}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)})))?ve.success(t,"OK"):ve.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>x(this,void 0,void 0,(function*(){if(!this._model)return ve.error(s,"Internal Server Error");e||(e={});const i=Object.assign({},e);i.where=i.where?Object.assign({},i.where):{};const{id:n}=r.params,o=yield this._model.findByPk(n,i).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));return o?ve.data(s,t?t(o):o.toJSON()):null===o?ve.notfound(s,"Record not found"):ve.error(s,"Internal Server Error")}))}name(){var e;return this._model?null===(e=this._model)||void 0===e?void 0:e.tableName:super.name()}set(){return(e,t)=>x(this,void 0,void 0,(function*(){if(!this._model)return ve.error(t,"Internal Server Error");const{id:r}=e.params,[s]=(yield this._model.update(e.body,{where:{id:r}}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)})))||[];return s?ve.success(t,"OK"):ve.success(t,"Record not changed")}))}getModel(){return this._model}setModel(e){this._model=e}}class Oe extends Ee{intialize(){const e=this.model();e&&this.setModel(e),this.router.use(this.auth),this.router.get("/",this.read(),this.all().bind(this)),this.router.post("/",this.write(),this.validation(this.create()),this.add().bind(this)),this.router.route("/:id").get(this.read(),this.get().bind(this)).put(this.write(),this.validation(this.update()),this.set().bind(this)).delete(this.write(),this.del().bind(this))}}class Re extends Oe{create(){return{name:i.string().required(),description:i.string().empty(""),state:i.boolean().required()}}model(){return oe}update(){return{name:i.string().empty(),description:i.string().empty(),state:i.boolean().empty()}}}class qe extends Ee{constructor(){super(...arguments),this.groups={groups:i.array().items(i.number())}}intialize(){this.setModel(de),this.router.use(this.auth),this.router.route("/:id/groups").get(this.read("users"),this.groupRouteAll.bind(this)).put(this.write("users"),this.validation(this.groups),this.groupRouteSet.bind(this))}groupRouteAll(e,t){return x(this,void 0,void 0,(function*(){const{id:r}=e.params;return this.all({where:{groupId:r},include:[{model:ae,required:!0}]},(e=>e.map((e=>e.route))))(e,t)}))}groupRouteSet(e,t){return x(this,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,i=yield oe.findByPk(r,{attributes:["id"]}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));if(i){const e=i.id;if(yield de.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield ae.count({where:{id:s[r]}}),t&&(yield de.create({groupId:e,routeId:s[r]}))}return ve.success(t,"OK")}return null===i?ve.notfound(t,"Record not found"):ve.error(t,"Internal Server Error")}))}}class Ne extends Ee{intialize(){this.setModel(he),this.router.use(this.auth),this.router.get("/",this.read("logs"),this.logsAll.bind(this))}logsAll(e,t){return x(this,void 0,void 0,(function*(){const{source:r,type:s}=e.query,i=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return this.all({where:i,order:[["created","DESC"]]})(e,t)}))}}class Pe extends Oe{create(){return{name:i.string().required(),description:i.string().empty(""),state:i.boolean().required()}}model(){return ae}update(){return{name:i.string().empty(),description:i.string().empty(),state:i.boolean().empty()}}}class ke extends Ee{constructor(){super(...arguments),this.attributes=["id","name","email","username","description","state"],this.create={name:i.string().required(),email:i.string().email().required(),username:i.string().min(4).required(),password:i.string().min(5).required(),description:i.string().required(),state:i.boolean().required()},this.update={name:i.string().empty(),email:i.string().email().empty(),username:i.string().min(4).empty(),password:i.string().min(5).empty(),description:i.string().empty(),state:i.boolean().empty()}}intialize(){this.setModel(ue),this.router.use(this.auth),this.router.get("/",this.read(),this.userAll.bind(this)),this.router.post("/",this.write(),this.validation(this.create),this.userAdd.bind(this)),this.router.route("/:id").get(this.read(),this.userGet.bind(this)).put(this.write(),this.validation(this.update),this.userSet.bind(this)).delete(this.write(),this.userDel.bind(this))}userAdd(e,t){return x(this,void 0,void 0,(function*(){return e.body.password=k(e.body.password).toString(),yield this.add()(e,t)}))}userAll(e,t){return x(this,void 0,void 0,(function*(){return this.all({attributes:this.attributes})(e,t)}))}userDel(e,t){return x(this,void 0,void 0,(function*(){const r=e.user;if(r){const{id:s}=e.params;if(r.id.toString()!=s)return this.del()(e,t)}return ve.error(t,"Internal Server Error")}))}userGet(e,t){return x(this,void 0,void 0,(function*(){return this.get({attributes:this.attributes})(e,t)}))}userSet(e,t){return x(this,void 0,void 0,(function*(){return e.body.password&&(e.body.password=k(e.body.password).toString()),this.set()(e,t)}))}}class xe extends Ee{constructor(){super(...arguments),this.groups={groups:i.array(i.number())}}intialize(){this.setModel(ce),this.router.use(this.auth),this.router.route("/:id/groups").get(this.read("groups"),this.userGroupsAll.bind(this)).put(this.write("groups"),this.validation(this.groups),this.userGroupsSet.bind(this))}userGroupsAll(e,t){return x(this,void 0,void 0,(function*(){const{id:r}=e.params;return this.all({where:{userId:r},include:[{model:oe,required:!0}]},(e=>e.map((e=>e.group))))(e,t)}))}userGroupsSet(e,t){return x(this,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,i=yield ue.findByPk(r,{attributes:["id"]}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));if(i){if(yield ce.destroy({where:{userId:i.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield oe.count({where:{id:s[t]}}),e&&(yield ce.create({userId:i.id,groupId:s[t]}))}return ve.success(t,"OK")}return ve.notfound(t,"Record not found")}))}}export{z as API_AUTH_SLEEP,D as API_DB_DATABASE,G as API_DB_HOST,U as API_DB_LOG,j as API_DB_PASSWORD,B as API_DB_PORT,M as API_DB_TYPE,C as API_DB_USERNAME,W as API_HTTP_CROSS,L as API_HTTP_CRT,X as API_HTTP_HYBRID,H as API_HTTP_KEY,K as API_HTTP_PORT,F as API_HTTP_PUBLIC,Y as API_TOKEN_CRT,$ as API_TOKEN_HEADER,J as API_TOKEN_KEY,Z as API_TOKEN_LIFETIME,Q as API_UPLOAD_COUNT,V as API_UPLOAD_FIELD,ee as API_UPLOAD_SIZE,te as API_UPLOAD_TEMP,re as API_WEBSOCKET_START,Ie as App,ne as Auth,Te as AuthController,be as Config,le as Configs,Ae as Controller,Oe as CrudController,se as Database,oe as Group,Re as GroupController,de as GroupRoute,qe as GroupRouteController,me as Log,he as Logs,Ne as LogsController,Ee as ModelController,Se as Permission,ve as Responses,ae as Route,Pe as RouteController,we as Token,ue as User,ke as UserController,ce as UserGroup,xe as UserGroupController,fe as crt,ye as key,ie as sequelize};
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@andrewcaires/api",
3
- "version": "1.0.11",
3
+ "version": "2.0.0",
4
4
  "description": "Simple api for small applications using express, jsonwebtoken, sequelize and websocket",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
9
  "build": "rollup -c build/rollup.config.js",
10
- "dev": "ts-node-dev --respawn --transpile-only ./src/test.ts",
10
+ "dev": "ts-node-dev --respawn --transpile-only ./src/dev.ts",
11
11
  "lint": "eslint . --ext .ts --fix"
12
12
  },
13
13
  "repository": {
@@ -35,13 +35,11 @@
35
35
  },
36
36
  "homepage": "https://github.com/andrewcaires/npm/tree/main/api#readme",
37
37
  "dependencies": {
38
- "@andrewcaires/utils.js": "^0.1.9",
38
+ "@andrewcaires/utils.js": "^0.2.0",
39
39
  "cors": "^2.8.5",
40
40
  "crypto-js": "^4.1.1",
41
41
  "dotenv": "^16.0.3",
42
- "express": "^4.18.1",
43
- "fs": "^0.0.1-security",
44
- "joi": "^17.6.2",
42
+ "express": "^4.18.2",
45
43
  "jsonwebtoken": "^8.5.1",
46
44
  "mariadb": "^3.0.1",
47
45
  "mime-types": "^2.1.35",
@@ -49,25 +47,26 @@
49
47
  "mysql2": "^2.3.3",
50
48
  "pg": "^8.8.0",
51
49
  "pg-hstore": "^2.3.4",
52
- "sequelize": "^6.24.0",
50
+ "sequelize": "^6.25.0",
51
+ "sqlite3": "^5.1.2",
53
52
  "ws": "^8.9.0"
54
53
  },
55
54
  "devDependencies": {
56
- "@rollup/plugin-commonjs": "^22.0.2",
57
- "@rollup/plugin-typescript": "^8.5.0",
55
+ "@rollup/plugin-commonjs": "^23.0.0",
56
+ "@rollup/plugin-typescript": "^9.0.1",
58
57
  "@types/cors": "^2.8.12",
59
58
  "@types/crypto-js": "^4.1.1",
60
59
  "@types/express": "^4.17.14",
61
60
  "@types/jsonwebtoken": "^8.5.9",
62
61
  "@types/mime-types": "^2.1.1",
63
62
  "@types/multer": "^1.4.7",
64
- "@types/node": "^18.8.3",
63
+ "@types/node": "^18.8.5",
65
64
  "@types/ws": "^8.5.3",
66
- "@typescript-eslint/eslint-plugin": "^5.39.0",
67
- "@typescript-eslint/parser": "^5.39.0",
68
- "eslint": "^8.24.0",
65
+ "@typescript-eslint/eslint-plugin": "^5.40.0",
66
+ "@typescript-eslint/parser": "^5.40.0",
67
+ "eslint": "^8.25.0",
69
68
  "rollup": "^2.79.1",
70
- "rollup-plugin-dts": "^4.2.2",
69
+ "rollup-plugin-dts": "^4.2.3",
71
70
  "rollup-plugin-terser": "^7.0.2",
72
71
  "ts-node": "^10.9.1",
73
72
  "ts-node-dev": "^2.0.0",