@andrewcaires/api 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @andrewcaires/api v3.0.1
2
+ * @andrewcaires/api v3.0.2
3
3
  * Simple api for small applications using express, jsonwebtoken, sequelize and websocket
4
4
  * (c) 2023 Andrew Caires
5
5
  * @license: MIT
6
6
  */
7
- "use strict";var e=require("@andrewcaires/express"),t=require("@andrewcaires/utils.js"),r=require("ws"),s=require("sequelize"),o=require("dotenv"),n=require("fs"),i=require("jsonwebtoken"),a=require("crypto-js"),d=require("mime-types"),u=require("multer"),l=require("path");function c(e,t,r,s){var o,n=arguments.length,i=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,r):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,r,s);else for(var a=e.length-1;a>=0;a--)(o=e[a])&&(i=(n<3?o(i):n>3?o(t,r,i):o(t,r))||i);return n>3&&i&&Object.defineProperty(t,r,i),i}function p(e,t){return function(r,s){t(r,s,e)}}function g(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function y(e,t,r,s){return new(r||(r=Promise))((function(o,n){function i(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?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,a)}d((s=s.apply(e,t||[])).next())}))}o.config();class m{}m.API_CONSOLE_ERROR=t.toBool(process.env.API_CONSOLE_ERROR||"false"),m.API_DB_DATABASE=process.env.API_DB_DATABASE||"",m.API_DB_HOST=process.env.API_DB_HOST||"127.0.0.1",m.API_DB_PASSWORD=process.env.API_DB_PASSWORD||"",m.API_DB_PORT=parseInt(process.env.API_DB_PORT||"3306"),m.API_DB_TYPE=process.env.API_DB_TYPE||"",m.API_DB_USERNAME=process.env.API_DB_USERNAME||"root",m.API_DB_LOG=t.toBool(process.env.API_DB_LOG||"false"),m.API_TABLE_PREFIX=process.env.API_TABLE_PREFIX||"",m.API_HTTP_CRT=process.env.API_HTTP_CRT||"",m.API_HTTP_KEY=process.env.API_HTTP_KEY||"",m.API_HTTP_PORT=parseInt(process.env.API_HTTP_PORT||"3000"),m.API_HTTP_PUBLIC=process.env.API_HTTP_PUBLIC||"",m.API_HTTP_CROSS=t.toBool(process.env.API_HTTP_CROSS||"false"),m.API_HTTP_HYBRID=t.toBool(process.env.API_HTTP_HYBRID||"false"),m.API_SLEEP_AUTH=parseInt(process.env.API_SLEEP_AUTH||"1000"),m.API_SLEEP_FORGOT=parseInt(process.env.API_SLEEP_FORGOT||"5000"),m.API_SLEEP_REGISTRY=parseInt(process.env.API_SLEEP_REGISTRY||"5000"),m.API_TOKEN_CRT=process.env.API_TOKEN_CRT||"",m.API_TOKEN_KEY=process.env.API_TOKEN_KEY||"",m.API_TOKEN_HEADER=process.env.API_TOKEN_HEADER||"authorization",m.API_TOKEN_LIFETIME=parseInt(process.env.API_TOKEN_LIFETIME||"15"),m.API_UPLOAD_COUNT=parseInt(process.env.API_UPLOAD_COUNT||"1"),m.API_UPLOAD_FIELD=process.env.API_UPLOAD_FIELD||"upload",m.API_UPLOAD_SIZE=parseInt(process.env.API_UPLOAD_SIZE||"2"),m.API_UPLOAD_TEMP=process.env.API_UPLOAD_TEMP||"./temp",m.API_WEBSOCKET_START=t.toBool(process.env.API_WEBSOCKET_START||"false");class h{static connect(e){const t="connect_"+m.API_DB_TYPE.toLowerCase();if(t in h)return h[t](e);throw new Error("No database is connected to this API")}static connect_mariadb(e){return new s.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mariadb",logging:m.API_DB_LOG,define:{timestamps:!1}})}static connect_memory(){return new s.Sequelize("sqlite::memory:",{logging:m.API_DB_LOG,define:{timestamps:!1}})}static connect_mysql(e){return new s.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mysql",logging:m.API_DB_LOG,define:{timestamps:!1}})}static connect_postgres(e){return new s.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"postgres",logging:m.API_DB_LOG,define:{timestamps:!1}})}static connect_sqlite(e){return new s.Sequelize({dialect:"sqlite",storage:e.database,logging:m.API_DB_LOG,define:{timestamps:!1}})}}const R=h.connect({database:m.API_DB_DATABASE,username:m.API_DB_USERNAME,password:m.API_DB_PASSWORD,hostname:m.API_DB_HOST,hostport:m.API_DB_PORT});class v extends s.Model{}v.init({login:s.DataTypes.BIGINT,logout:s.DataTypes.BIGINT,secret:s.DataTypes.STRING,timestamp:s.DataTypes.BIGINT,useragent:s.DataTypes.STRING},{sequelize:R,modelName:m.API_TABLE_PREFIX+"auth",timestamps:!0,createdAt:"created",updatedAt:"updated"});class A extends s.Model{}A.init({token:s.DataTypes.STRING,timestamp:s.DataTypes.BIGINT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"forgot",timestamps:!0,createdAt:"created",updatedAt:"updated"});class O extends s.Model{}O.init({name:s.DataTypes.STRING,description:s.DataTypes.TEXT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"group",timestamps:!0,createdAt:"created",updatedAt:"updated"});class I extends s.Model{}I.init({name:s.DataTypes.STRING,description:s.DataTypes.TEXT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"route",timestamps:!0,createdAt:"created",updatedAt:"updated"});class _ extends s.Model{}_.init({},{sequelize:R,modelName:m.API_TABLE_PREFIX+"groups_routes",timestamps:!0,createdAt:"created",updatedAt:!1}),_.removeAttribute("id");class P extends s.Model{}P.init({name:s.DataTypes.STRING,email:s.DataTypes.STRING,username:s.DataTypes.STRING,password:s.DataTypes.STRING,avatar:s.DataTypes.STRING,description:s.DataTypes.TEXT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"user",timestamps:!0,createdAt:"created",updatedAt:"updated"});class f extends s.Model{}f.init({},{sequelize:R,modelName:m.API_TABLE_PREFIX+"users_groups",timestamps:!0,createdAt:"created",updatedAt:!1}),f.removeAttribute("id");class T extends s.Model{}T.init({key:s.DataTypes.STRING,value:s.DataTypes.STRING},{sequelize:R,modelName:m.API_TABLE_PREFIX+"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),T.removeAttribute("id");class E extends s.Model{}var w;E.init({type:s.DataTypes.STRING,source:s.DataTypes.STRING,message:s.DataTypes.TEXT},{sequelize:R,modelName:m.API_TABLE_PREFIX+"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),P.hasMany(v),v.belongsTo(P),P.hasMany(A),A.belongsTo(P),O.hasMany(_),_.belongsTo(O),I.hasMany(_),_.belongsTo(I),P.hasMany(f),f.belongsTo(P),O.hasMany(f),f.belongsTo(O),function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(w||(w={}));class b{static write(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.NONE,"",e,t,r)}))}static error(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.ERROR,"error",e,t,r)}))}static info(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.INFO,"info",e,t,r)}))}static success(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.ERROR,"success",e,t,r)}))}static warning(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.WARNING,"warning",e,t,r)}))}static writeConsole(e,r,s){const o=t.dateFormat(new Date,"%H:%M:%S");console.log(">",e,r+" ".repeat(10-r.length),"","|",o,"|",s)}static writeRaw(e,t,r,s,o){return y(this,void 0,void 0,(function*(){o&&b.writeConsole(e,t,r),R&&(yield E.create({type:t,source:s,message:r}).catch((()=>null)))}))}}const S=e=>n.existsSync(e)?n.readFileSync(e):void 0,q={http:S(m.API_HTTP_CRT),token:S(m.API_TOKEN_CRT)},x={http:S(m.API_HTTP_KEY),token:S(m.API_TOKEN_KEY)};class C{static error(e){b.error(e.message,"api.token",m.API_CONSOLE_ERROR)}static sign(e){return x.token?{token:i.sign(e,x.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static user(e){return y(this,void 0,void 0,(function*(){const{error:t,decode:r}=C.verify(e);if(t)return{error:t};if(r){const{id:e,secret:t}=r;if(e&&r){const r=yield P.findOne({where:{id:e,state:!0}}).catch(C.error);if(r){const e=yield v.findOne({where:{secret:t,userId:r.id}}).catch(C.error);if(e){const t=Date.now();if(t>e.timestamp)return e.logout=t,yield e.save(),{error:"Expired token"};if(e.timestamp=t+6e4*m.API_TOKEN_LIFETIME,!e.logout)return yield e.save(),{auth:e,user:r}}}return{error:"Access denied"}}}return{error:"Invalid token"}}))}static verify(e){if(!q.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:i.verify(e,q.token)}}catch(e){return{error:"Invalid Token"}}}}class D extends e.Application{constructor(e){super(e,{cert:q.http,cross:m.API_HTTP_CROSS,hybrid:m.API_HTTP_HYBRID,key:x.http,path:"/api",port:m.API_HTTP_PORT,public:m.API_HTTP_PUBLIC})}error(e,t){b.info(e.message,t,m.API_CONSOLE_ERROR)}log(e,t){b.info(e,t,!0)}listen(){const e=Object.create(null,{listen:{get:()=>super.listen}});return y(this,void 0,void 0,(function*(){yield R.sync(),yield e.listen.call(this),m.API_WEBSOCKET_START&&this.server&&(this._webSocket=new r.Server({server:this.server,verifyClient:(e,t)=>t(m.API_WEBSOCKET_START)}),this._webSocket.on("connection",((e,r)=>y(this,void 0,void 0,(function*(){r.url||(r.url="");const s=r.url.length<=1?"":r.url.replace(/\//g,".");let o;e.on("message",(t=>y(this,void 0,void 0,(function*(){if(o)try{const n=JSON.parse(t);this.emit("ws.message"+s,{data:n,message:t,req:r,user:o,ws:e})}catch(n){this.emit("ws.message"+s,{message:t,req:r,user:o,ws:e})}else{const{user:n}=yield C.user(t.toString());n&&(o=n,this.emit("ws.connection"+s,{req:r,user:o,ws:e}))}o||e.close()})))),e.on("close",(()=>{o&&this.emit("ws.close"+s,{user:o,ws:e})})),yield t.sleep(2e3),o||e.close()})))))}))}websocket(){return this._webSocket}}class j{static all(){return y(this,void 0,void 0,(function*(){const e=yield T.findAll().catch(j.error),t={};return e&&e.forEach((e=>{t[e.key]=e.value})),t}))}static del(e){return y(this,void 0,void 0,(function*(){return((yield T.destroy({where:{key:e}}).catch(j.error))||0)>0}))}static error(e){b.error(e.message,"api.config",m.API_CONSOLE_ERROR)}static get(e){return y(this,void 0,void 0,(function*(){const t=yield T.findOne({where:{key:e}}).catch(j.error);return t&&t.value||""}))}static set(e,t){return y(this,void 0,void 0,(function*(){const[r]=(yield T.findOrCreate({where:{key:e}}).catch(j.error))||[];r&&(r.value=t,yield r.save().catch(j.error))}))}}class N{static all(e,t){return y(this,void 0,void 0,(function*(){return yield I.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:_,required:!0,include:[{model:O,required:!0,where:{state:!0},include:[{model:f,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{b.error(e.message,"api.permission",m.API_CONSOLE_ERROR)}))}))}static get(e){return y(this,void 0,void 0,(function*(){const t=yield N.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return y(this,void 0,void 0,(function*(){const r=yield N.all(e,{name:t});return!!r&&r.length>0}))}}const F=e.parameterFactory((({req:e})=>e.auth)),B=e.parameterFactory((({req:e})=>e.user)),G=(e,r)=>{const s=t.uuidv4()+"."+r;return n.existsSync(l.join(e,s))?G(e,r):s};class M extends t.EventEmitter{auth(t,r,s,o,n){return y(this,void 0,void 0,(function*(){const{auth:i,error:a,user:d}=yield C.user(s);return a?e.Responses.error(t,a):i&&d?(o&&(i.useragent=o),yield i.save(),r.auth=i,r.user=d,n()):e.Responses.error(t,"Internal Server Error")}))}error(e){b.error(e.message,"api.controller",m.API_CONSOLE_ERROR)}name(){return"api"}permission(t,r,s,o){return y(this,void 0,void 0,(function*(){return r?(yield N.is(r,o))?s():e.Responses.error(t,"Unauthorized access"):e.Responses.unauthorized(t,"Access denied")}))}read(e,t,r,s){return this.permission(e,t,r,(s||this.name())+".read")}upload(t,r,s,o){const n=(null==o?void 0:o.path)||m.API_UPLOAD_TEMP,i=u.diskStorage({destination:(e,t,r)=>r(null,n),filename:(e,t,r)=>y(this,void 0,void 0,(function*(){return r(null,G(n,d.extension(t.mimetype)||"bin"))}))}),a=1e6*((null==o?void 0:o.size)||m.API_UPLOAD_SIZE),l=u({storage:i,fileFilter(e,t,r){var s;return y(this,void 0,void 0,(function*(){const e=null===(s=null==o?void 0:o.types)||void 0===s?void 0:s.indexOf(t.mimetype);return void 0!==e&&e<0?r(new Error("File type not allowed")):r(null,!0)}))},limits:{fileSize:a}}),c=(null==o?void 0:o.count)||m.API_UPLOAD_COUNT,p=(null==o?void 0:o.field)||m.API_UPLOAD_FIELD;l.array(p,c)(r,t,(r=>r?e.Responses.error(t,r.message):s()))}validation(r,s,o,n){return y(this,void 0,void 0,(function*(){const{error:i,value:a}=yield t.Validation.object(n).validateAsync(s.body);return i?e.Responses.validation(r,i):(s.body=a,o())}))}write(e,t,r,s){return this.permission(e,t,r,(s||this.name())+".write")}}c([p(0,e.Res()),p(1,e.Req()),p(2,e.Headers(m.API_TOKEN_HEADER)),p(3,e.Headers("user-agent")),p(4,e.Next()),g("design:type",Function),g("design:paramtypes",[Object,Object,String,String,Function]),g("design:returntype",Promise)],M.prototype,"auth",null),c([p(0,e.Res()),p(1,B()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,P,Function,String]),g("design:returntype",Promise)],M.prototype,"permission",null),c([p(0,e.Res()),p(1,B()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,P,Function,String]),g("design:returntype",void 0)],M.prototype,"read",null),c([p(0,e.Res()),p(1,e.Req()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function,Object]),g("design:returntype",void 0)],M.prototype,"upload",null),c([p(0,e.Res()),p(1,e.Req()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function,Object]),g("design:returntype",Promise)],M.prototype,"validation",null),c([p(0,e.Res()),p(1,B()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,P,Function,String]),g("design:returntype",void 0)],M.prototype,"write",null),exports.AuthController=class extends M{constructor(){super(...arguments),this.attributes=["id","name","email","username","avatar"]}login(r,s,o,n){return y(this,void 0,void 0,(function*(){yield t.sleep(m.API_SLEEP_AUTH);const{username:i,password:d}=s.body,u=yield P.findOne({where:{username:i}}).catch(this.error);if(!u)return n.emit("auth.failure",{req:s}),e.Responses.notfound(r,"Username not found");if(!u.state)return n.emit("auth.failure",{req:s}),e.Responses.error(r,"Username is disabled");const l=a.SHA256(d).toString();if(u.password!=l)return n.emit("auth.failure",{req:s}),e.Responses.error(r,"Invalid password");const c=u.id,p=t.uniqueID(),{error:g,token:y}=C.sign({id:c,secret:p});if(g)return n.emit("auth.failure",{req:s}),e.Responses.error(r,g);if(y){const t=Date.now(),n=t+6e4*m.API_TOKEN_LIFETIME,i=yield v.create({login:t,secret:p,timestamp:n,useragent:o,userId:c}).catch(this.error);if(i)return this.emit("auth.login",{auth:i,req:s,user:u}),e.Responses.data(r,{token:y})}return n.emit("auth.failure",{req:s}),e.Responses.error(r,"Internal Server Error")}))}logout(t,r,s,o,n){return y(this,void 0,void 0,(function*(){return s&&o&&!s.logout?(s.logout=Date.now(),s.timestamp=s.logout,yield s.save(),n.emit("auth.logout",{auth:s,req:r,user:o}),e.Responses.success(t,"Disconcerted")):e.Responses.unauthorized(t,"Access denied")}))}user(r,s){return y(this,void 0,void 0,(function*(){const o=s.user;if(!o)return e.Responses.unauthorized(r,"Access denied");const n=yield N.all(o);if(n){const s=n.map((e=>e.name));return e.Responses.data(r,Object.assign(Object.assign({},t.allowedObject(this.attributes,o.toJSON())),{permissions:s}))}return e.Responses.error(r,"Internal Server Error")}))}},c([e.Post("/login"),e.Middleware("validation",{username:t.Validation.string().min(4).required(),password:t.Validation.string().min(5).required()}),p(0,e.Res()),p(1,e.Req()),p(2,e.Headers("user-agent")),p(3,e.App()),g("design:type",Function),g("design:paramtypes",[Object,Object,String,D]),g("design:returntype",Promise)],exports.AuthController.prototype,"login",null),c([e.Get("/logout"),e.Middleware("auth"),p(0,e.Res()),p(1,e.Req()),p(2,F()),p(3,B()),p(4,e.App()),g("design:type",Function),g("design:paramtypes",[Object,Object,v,P,D]),g("design:returntype",Promise)],exports.AuthController.prototype,"logout",null),c([e.Get(),e.Middleware("auth"),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.AuthController.prototype,"user",null),exports.AuthController=c([e.Controller("/auth")],exports.AuthController),exports.ForgotController=class extends M{check(r,s){return y(this,void 0,void 0,(function*(){const{token:o}=s.body,n=yield this.findOne(o);return n&&n.user?(n.token=t.uniqueID(),yield n.save(),e.Responses.data(r,{token:n.token})):e.Responses.notfound(r,"User not found")}))}forgot(r,s){return y(this,void 0,void 0,(function*(){const{username:o}=s.body;yield t.sleep(m.API_SLEEP_FORGOT);const n=yield P.findOne({where:{username:o}}).catch(this.error);if(!n)return e.Responses.notfound(r,"User not found");const i=t.uniqueID(),a=Date.now()+6e4*m.API_TOKEN_LIFETIME,d=yield A.create({token:i,timestamp:a,state:!0,userId:n.id});return this.emit("forgot",{forgot:d,req:s,user:n}),e.Responses.success(r,"OK")}))}reset(t,r){return y(this,void 0,void 0,(function*(){const{token:s,password:o}=r.body,n=yield this.findOne(s);return n?(n.state=!1,yield n.save().catch(this.error),n.user.password=a.SHA256(o).toString(),yield n.user.save().catch(this.error),this.emit("forgot.reset",{req:r,user:n.user}),e.Responses.success(t,"OK")):e.Responses.notfound(t,"User not found")}))}findOne(e){return y(this,void 0,void 0,(function*(){return yield A.findOne({where:{token:e,state:!0},include:[{model:P,required:!0}]}).catch(this.error)}))}},c([e.Get("/check"),e.Middleware("validation",{token:t.Validation.string().required()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.ForgotController.prototype,"check",null),c([e.Get(),e.Middleware("validation",{username:t.Validation.string().min(4).required()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.ForgotController.prototype,"forgot",null),c([e.Get("/reset"),e.Middleware("validation",{token:t.Validation.string().required(),password:t.Validation.string().min(5).required()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.ForgotController.prototype,"reset",null),exports.ForgotController=c([e.Controller("/forgot")],exports.ForgotController);class L extends M{add(t,r,s){return y(this,void 0,void 0,(function*(){const o=yield this.model().create(t.body,s||{}).catch(this.error);return o?e.Responses.data(r,{id:o.id}):e.Responses.error(r,"Internal Server Error")}))}all(r,o,n,i){var a,d,u,l,c;return y(this,void 0,void 0,(function*(){const p=this.model(),g=Object.assign({},n||{});g.where=Object.assign({},g.where||{});const y=null===(a=r.query.limit)||void 0===a?void 0:a.toString();y&&(g.limit=parseInt(y));const m=null===(d=r.query.offset)||void 0===d?void 0:d.toString();m&&(g.offset=parseInt(m));const h=Object.keys(p.getAttributes()),R=[],v=null===(u=r.query.asc)||void 0===u?void 0:u.toString();v&&v.length&&v.split(",").forEach((e=>{h.indexOf(e)>=0&&R.push([e,"ASC"])}));const A=null===(l=r.query.desc)||void 0===l?void 0:l.toString();A&&A.length&&A.split(",").forEach((e=>{h.indexOf(e)>=0&&R.push([e,"DESC"])})),R.length&&(g.order=R);const O=[],I=t.isArray(g.attributes)?g.attributes:h,_=null===(c=r.query.search)||void 0===c?void 0:c.toString();I.forEach((e=>{var o;if(t.isString(e)&&(_&&_.length&&O.push({[e]:{[s.Op.like]:`%${_}%`}}),"search_"+e in r.query)){const t=null===(o=r.query["search_"+e])||void 0===o?void 0:o.toString();t&&t.length&&O.push({[e]:{[s.Op.like]:`%${t}%`}})}})),O.length&&(g.where=Object.assign(Object.assign({},g.where),{[s.Op.or]:[...O]}));const P=yield p.count(Object.assign(Object.assign({},g),{col:h[0]})).catch(this.error),f=yield p.findAll(g).catch(this.error);return f?e.Responses.data(o,{count:P,records:i?i(f):f}):e.Responses.error(o,"Internal Server Error")}))}del(t,r,s){return y(this,void 0,void 0,(function*(){const{id:o}=t.params;if(!o)return e.Responses.error(r,"Internal Server Error");return(yield this.model().destroy(Object.assign(Object.assign({},s||{}),{where:{id:o}})).catch(this.error))?e.Responses.success(r,"OK"):e.Responses.notfound(r,"Record not found")}))}error(e){e.sql?b.error(e.message+"\n"+e.sql,"api.controller.sql",m.API_CONSOLE_ERROR):super.error(e)}get(t,r,s,o){return y(this,void 0,void 0,(function*(){const n=Object.assign({},s||{});n.where=n.where?Object.assign({},n.where):{};const{id:i}=t.params,a=yield this.model().findByPk(i,n).catch(this.error);return a?e.Responses.data(r,o?o(a):a.toJSON()):null===a?e.Responses.notfound(r,"Record not found"):e.Responses.error(r,"Internal Server Error")}))}name(){return this.model().tableName}set(t,r,s){return y(this,void 0,void 0,(function*(){const{id:o}=t.params,[n]=(yield this.model().update(t.body,Object.assign(Object.assign({},s||{}),{where:Object.assign(Object.assign({},(s||{}).where),{id:o})})).catch(this.error))||[];return n?e.Responses.success(r,"OK"):e.Responses.success(r,"Record not changed")}))}}class k extends L{create(){return{}}recordAdd(e,t){return this.add(e,t)}recordAll(e,t){return this.all(e,t)}recordDel(e,t){return this.del(e,t)}recordGet(e,t){return this.get(e,t)}recordSet(e,t){return this.set(e,t)}update(){return{}}validationAdd(e,t,r){return this.validation(t,e,r,this.create())}validationSet(e,t,r){return this.validation(t,e,r,this.update())}}c([e.Post(),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validationAdd"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordAdd",null),c([e.Get(),e.Middleware("auth"),e.Middleware("read"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordAll",null),c([e.Delete("/:id"),e.Middleware("auth"),e.Middleware("write"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordDel",null),c([e.Get("/:id"),e.Middleware("auth"),e.Middleware("read"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordGet",null),c([e.Put("/:id"),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validationSet"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordSet",null),c([p(0,e.Req()),p(1,e.Res()),p(2,e.Next()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function]),g("design:returntype",void 0)],k.prototype,"validationAdd",null),c([p(0,e.Req()),p(1,e.Res()),p(2,e.Next()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function]),g("design:returntype",void 0)],k.prototype,"validationSet",null),exports.GroupController=class extends k{model(){return O}create(){return{name:t.Validation.string().required(),description:t.Validation.string().empty(""),state:t.Validation.boolean().parse().required()}}update(){return{name:t.Validation.string().empty(),description:t.Validation.string().empty(),state:t.Validation.boolean().parse().empty()}}},exports.GroupController=c([e.Controller("/groups")],exports.GroupController),exports.GroupRouteController=class extends L{model(){return _}groupRouteAll(e,t,r){return y(this,void 0,void 0,(function*(){return this.all(t,e,{where:{groupId:r},include:[{model:I,required:!0}]},(e=>e.map((e=>e.route))))}))}groupRouteSet(r,s,o){return y(this,void 0,void 0,(function*(){const n=yield O.findByPk(s,{attributes:["id"]}).catch(this.error);if(n){const t=n.id;if(yield _.destroy({where:{groupId:t}}),o){let e=0;for(let r=0;r<o.length;r++)e=yield I.count({where:{id:o[r]}}),e&&(yield _.create({groupId:t,routeId:o[r]}))}return e.Responses.success(r,"OK")}return t.isNull(n)?e.Responses.notfound(r,"Record not found"):e.Responses.error(r,"Internal Server Error")}))}},c([e.Get("/:id/routes"),e.Middleware("auth"),e.Middleware("read","routes"),p(0,e.Res()),p(1,e.Req()),p(2,e.Params("id")),g("design:type",Function),g("design:paramtypes",[Object,Object,String]),g("design:returntype",Promise)],exports.GroupRouteController.prototype,"groupRouteAll",null),c([e.Put("/:id/groups"),e.Middleware("auth"),e.Middleware("write","groups"),e.Middleware("validation",{routes:t.Validation.array(t.Validation.number().parse())}),p(0,e.Res()),p(1,e.Params("id")),p(2,e.Body("routes")),g("design:type",Function),g("design:paramtypes",[Object,String,Array]),g("design:returntype",Promise)],exports.GroupRouteController.prototype,"groupRouteSet",null),exports.GroupRouteController=c([e.Controller("/groups")],exports.GroupRouteController),exports.LogsController=class extends L{model(){return E}logsAll(e,t){return y(this,void 0,void 0,(function*(){const{source:r,type:s}=t.query,o=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return this.all(t,e,{where:o,order:[["created","DESC"]]})}))}},c([e.Get(),e.Middleware("auth"),e.Middleware("read"),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.LogsController.prototype,"logsAll",null),exports.LogsController=c([e.Controller("/logs")],exports.LogsController);class U extends s.Model{}U.init({token:s.DataTypes.STRING,timestamp:s.DataTypes.BIGINT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"registry",timestamps:!0,createdAt:"created",updatedAt:"updated"}),exports.RegisterController=class extends M{confirm(t,r){return y(this,void 0,void 0,(function*(){const s=yield U.findOne({where:{token:r,state:!0},include:[{model:P,required:!0}]}).catch(this.error);return s?(s.user.state=!0,yield s.user.save().catch(this.error),this.emit("user.confirm",{user:s.user}),e.Responses.success(t,"OK")):e.Responses.notfound(t,"User not found")}))}register(r,s,o,n){return y(this,void 0,void 0,(function*(){yield t.sleep(m.API_SLEEP_REGISTRY);const s=yield P.findOne({where:{username:n}}).catch(this.error);if(s)return e.Responses.error(r,"Invalid Username");if(!t.isNull(s))return e.Responses.error(r,"Internal Server Error");const i=yield P.create(Object.assign(Object.assign({},o),{state:!1}));return this.emit("user.register",{user:i}),e.Responses.success(r,"OK")}))}},c([e.Get("/confirm"),e.Middleware("validation",{token:t.Validation.string().required()}),p(0,e.Res()),p(1,e.Body("token")),g("design:type",Function),g("design:paramtypes",[Object,String]),g("design:returntype",Promise)],exports.RegisterController.prototype,"confirm",null),c([e.Get(),e.Middleware("validation",{name:t.Validation.string().required(),email:t.Validation.string().email().required(),username:t.Validation.string().min(4).required(),password:t.Validation.string().min(5).required()}),p(0,e.Res()),p(1,e.Req()),p(2,e.Body()),p(3,e.Body("username")),g("design:type",Function),g("design:paramtypes",[Object,Object,Object,String]),g("design:returntype",Promise)],exports.RegisterController.prototype,"register",null),exports.RegisterController=c([e.Controller("/register")],exports.RegisterController),exports.RouteController=class extends k{model(){return I}create(){return{name:t.Validation.string().required(),description:t.Validation.string().empty(""),state:t.Validation.boolean().parse().required()}}update(){return{name:t.Validation.string().empty(),description:t.Validation.string().empty(),state:t.Validation.boolean().empty()}}},exports.RouteController=c([e.Controller("/routes")],exports.RouteController),exports.SetupController=class extends M{setup(r){return y(this,void 0,void 0,(function*(){if(0==(yield P.count())){const e={description:"",state:!0},r=yield P.create(Object.assign({name:"Admin",email:"admin@localhost",username:"admin",password:"8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",avatar:""},e)),s=yield O.create(Object.assign({name:"admin"},e));yield f.create({userId:r.id,groupId:s.id});const o=["read","write"],n=["users","groups","routes"];yield t.forEachSeries(n,(r=>y(this,void 0,void 0,(function*(){yield t.forEachSeries(o,(t=>y(this,void 0,void 0,(function*(){const o=r+"."+t,n=yield I.create(Object.assign({name:o},e));yield _.create({groupId:s.id,routeId:n.id})}))))}))));const i=yield I.create(Object.assign({name:"logs.read"},e));yield _.create({groupId:s.id,routeId:i.id})}return e.Responses.success(r,"OK")}))}},c([e.Get(),p(0,e.Res()),g("design:type",Function),g("design:paramtypes",[Object]),g("design:returntype",Promise)],exports.SetupController.prototype,"setup",null),exports.SetupController=c([e.Controller("/setup")],exports.SetupController),exports.UserController=class extends L{constructor(){super(...arguments),this.attributes=["id","name","email","username","avatar","description","state","created","updated"]}model(){return P}userAdd(e,t){return y(this,void 0,void 0,(function*(){return t.body.password=a.SHA256(t.body.password).toString(),yield this.add(t,e)}))}userAll(e,t){return y(this,void 0,void 0,(function*(){return this.all(t,e,{attributes:this.attributes})}))}userDel(t,r,s,o){return y(this,void 0,void 0,(function*(){return s&&s.id.toString()!=o?this.del(r,t):e.Responses.error(t,"Internal Server Error")}))}userGet(e,t){return y(this,void 0,void 0,(function*(){return this.get(t,e,{attributes:this.attributes})}))}userSet(e,t){return y(this,void 0,void 0,(function*(){return t.body.password&&(t.body.password=a.SHA256(t.body.password).toString()),this.set(t,e)}))}},c([e.Post(),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validation",{name:t.Validation.string().required(),email:t.Validation.string().email().required(),username:t.Validation.string().min(4).required(),password:t.Validation.string().min(5).required(),description:t.Validation.string().required(),state:t.Validation.boolean().parse().required()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userAdd",null),c([e.Get(),e.Middleware("auth"),e.Middleware("read"),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userAll",null),c([e.Delete("/:id"),e.Middleware("auth"),e.Middleware("write"),p(0,e.Res()),p(1,e.Req()),p(2,B()),p(3,e.Params("id")),g("design:type",Function),g("design:paramtypes",[Object,Object,P,String]),g("design:returntype",Promise)],exports.UserController.prototype,"userDel",null),c([e.Get("/:id"),e.Middleware("auth"),e.Middleware("read"),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userGet",null),c([e.Put("/:id"),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validation",{name:t.Validation.string().empty(),email:t.Validation.string().email().empty(),username:t.Validation.string().min(4).empty(),password:t.Validation.string().min(5).empty(),description:t.Validation.string().empty(),state:t.Validation.boolean().parse().empty()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userSet",null),exports.UserController=c([e.Controller("/users")],exports.UserController),exports.UserGroupController=class extends L{model(){return f}userGroupsAll(e,t,r){return y(this,void 0,void 0,(function*(){return this.all(t,e,{where:{userId:r},include:[{model:O,required:!0}]},(e=>e.map((e=>e.group))))}))}userGroupsSet(r,s,o){return y(this,void 0,void 0,(function*(){const n=yield P.findByPk(s,{attributes:["id"]}).catch(this.error);if(n){if(yield f.destroy({where:{userId:n.id}}),o){let e=0;for(let t=0;t<o.length;t++)e=yield O.count({where:{id:o[t]}}),e&&(yield f.create({userId:n.id,groupId:o[t]}))}return e.Responses.success(r,"OK")}return t.isNull(n)?e.Responses.notfound(r,"Record not found"):e.Responses.error(r,"Internal Server Error")}))}},c([e.Get("/:id/groups"),e.Middleware("auth"),e.Middleware("read","groups"),p(0,e.Res()),p(1,e.Req()),p(2,e.Params("id")),g("design:type",Function),g("design:paramtypes",[Object,Object,String]),g("design:returntype",Promise)],exports.UserGroupController.prototype,"userGroupsAll",null),c([e.Put("/:id/groups"),e.Middleware("auth"),e.Middleware("write","groups"),e.Middleware("validation",{groups:t.Validation.array(t.Validation.number().parse())}),p(0,e.Res()),p(1,e.Params("id")),p(2,e.Body("groups")),g("design:type",Function),g("design:paramtypes",[Object,String,Array]),g("design:returntype",Promise)],exports.UserGroupController.prototype,"userGroupsSet",null),exports.UserGroupController=c([e.Controller("/users")],exports.UserGroupController),exports.Application=D,exports.Auth=v,exports.Config=j,exports.Configs=T,exports.ControllerBase=M,exports.CrudController=k,exports.Database=h,exports.Env=m,exports.Forgot=A,exports.Group=O,exports.GroupRoute=_,exports.Log=b,exports.Logs=E,exports.ModelController=L,exports.Permission=N,exports.ReqAuth=F,exports.ReqUser=B,exports.Route=I,exports.Token=C,exports.User=P,exports.UserGroup=f,exports.crt=q,exports.key=x,exports.sequelize=R;
7
+ "use strict";var e=require("@andrewcaires/express"),t=require("@andrewcaires/utils.js"),r=require("ws"),s=require("sequelize"),o=require("dotenv"),n=require("fs"),i=require("jsonwebtoken"),a=require("crypto-js"),d=require("mime-types"),l=require("multer"),u=require("path");function c(e,t,r,s){var o,n=arguments.length,i=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,r):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,r,s);else for(var a=e.length-1;a>=0;a--)(o=e[a])&&(i=(n<3?o(i):n>3?o(t,r,i):o(t,r))||i);return n>3&&i&&Object.defineProperty(t,r,i),i}function p(e,t){return function(r,s){t(r,s,e)}}function g(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function y(e,t,r,s){return new(r||(r=Promise))((function(o,n){function i(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?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,a)}d((s=s.apply(e,t||[])).next())}))}o.config();class m{}m.API_CONSOLE_ERROR=t.toBool(process.env.API_CONSOLE_ERROR||"false"),m.API_DB_DATABASE=process.env.API_DB_DATABASE||"",m.API_DB_HOST=process.env.API_DB_HOST||"127.0.0.1",m.API_DB_PASSWORD=process.env.API_DB_PASSWORD||"",m.API_DB_PORT=parseInt(process.env.API_DB_PORT||"3306"),m.API_DB_TYPE=process.env.API_DB_TYPE||"",m.API_DB_USERNAME=process.env.API_DB_USERNAME||"root",m.API_DB_LOG=t.toBool(process.env.API_DB_LOG||"false"),m.API_TABLE_PREFIX=process.env.API_TABLE_PREFIX||"",m.API_HTTP_CRT=process.env.API_HTTP_CRT||"",m.API_HTTP_KEY=process.env.API_HTTP_KEY||"",m.API_HTTP_PORT=parseInt(process.env.API_HTTP_PORT||"3000"),m.API_HTTP_PUBLIC=process.env.API_HTTP_PUBLIC||"",m.API_HTTP_CROSS=t.toBool(process.env.API_HTTP_CROSS||"false"),m.API_HTTP_HYBRID=t.toBool(process.env.API_HTTP_HYBRID||"false"),m.API_SLEEP_AUTH=parseInt(process.env.API_SLEEP_AUTH||"1000"),m.API_SLEEP_FORGOT=parseInt(process.env.API_SLEEP_FORGOT||"5000"),m.API_SLEEP_REGISTRY=parseInt(process.env.API_SLEEP_REGISTRY||"5000"),m.API_TOKEN_CRT=process.env.API_TOKEN_CRT||"",m.API_TOKEN_KEY=process.env.API_TOKEN_KEY||"",m.API_TOKEN_HEADER=process.env.API_TOKEN_HEADER||"authorization",m.API_TOKEN_LIFETIME=parseInt(process.env.API_TOKEN_LIFETIME||"15"),m.API_UPLOAD_COUNT=parseInt(process.env.API_UPLOAD_COUNT||"1"),m.API_UPLOAD_FIELD=process.env.API_UPLOAD_FIELD||"upload",m.API_UPLOAD_SIZE=parseInt(process.env.API_UPLOAD_SIZE||"2"),m.API_UPLOAD_TEMP=process.env.API_UPLOAD_TEMP||"./temp",m.API_WEBSOCKET_START=t.toBool(process.env.API_WEBSOCKET_START||"false");class h{static connect(e){const t="connect_"+m.API_DB_TYPE.toLowerCase();if(t in h)return h[t](e);throw new Error("No database is connected to this API")}static connect_mariadb(e){return new s.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mariadb",logging:m.API_DB_LOG,define:{timestamps:!1}})}static connect_memory(){return new s.Sequelize("sqlite::memory:",{logging:m.API_DB_LOG,define:{timestamps:!1}})}static connect_mysql(e){return new s.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mysql",logging:m.API_DB_LOG,define:{timestamps:!1}})}static connect_postgres(e){return new s.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"postgres",logging:m.API_DB_LOG,define:{timestamps:!1}})}static connect_sqlite(e){return new s.Sequelize({dialect:"sqlite",storage:e.database,logging:m.API_DB_LOG,define:{timestamps:!1}})}}const R=h.connect({database:m.API_DB_DATABASE,username:m.API_DB_USERNAME,password:m.API_DB_PASSWORD,hostname:m.API_DB_HOST,hostport:m.API_DB_PORT});class v extends s.Model{}v.init({login:s.DataTypes.BIGINT,logout:s.DataTypes.BIGINT,secret:s.DataTypes.STRING,timestamp:s.DataTypes.BIGINT,useragent:s.DataTypes.STRING},{sequelize:R,modelName:m.API_TABLE_PREFIX+"auth",timestamps:!0,createdAt:"created",updatedAt:"updated"});class A extends s.Model{}A.init({token:s.DataTypes.STRING,timestamp:s.DataTypes.BIGINT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"forgot",timestamps:!0,createdAt:"created",updatedAt:"updated"});class O extends s.Model{}O.init({name:s.DataTypes.STRING,description:s.DataTypes.TEXT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"group",timestamps:!0,createdAt:"created",updatedAt:"updated"});class I extends s.Model{}I.init({name:s.DataTypes.STRING,description:s.DataTypes.TEXT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"route",timestamps:!0,createdAt:"created",updatedAt:"updated"});class _ extends s.Model{}_.init({},{sequelize:R,modelName:m.API_TABLE_PREFIX+"groups_routes",timestamps:!0,createdAt:"created",updatedAt:!1}),_.removeAttribute("id");class P extends s.Model{}P.init({name:s.DataTypes.STRING,email:s.DataTypes.STRING,username:s.DataTypes.STRING,password:s.DataTypes.STRING,avatar:s.DataTypes.STRING,description:s.DataTypes.TEXT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"user",timestamps:!0,createdAt:"created",updatedAt:"updated"});class f extends s.Model{}f.init({},{sequelize:R,modelName:m.API_TABLE_PREFIX+"users_groups",timestamps:!0,createdAt:"created",updatedAt:!1}),f.removeAttribute("id");class T extends s.Model{}T.init({key:s.DataTypes.STRING,value:s.DataTypes.STRING},{sequelize:R,modelName:m.API_TABLE_PREFIX+"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),T.removeAttribute("id");class E extends s.Model{}var w;E.init({type:s.DataTypes.STRING,source:s.DataTypes.STRING,message:s.DataTypes.TEXT},{sequelize:R,modelName:m.API_TABLE_PREFIX+"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),P.hasMany(v),v.belongsTo(P),P.hasMany(A),A.belongsTo(P),O.hasMany(_),_.belongsTo(O),I.hasMany(_),_.belongsTo(I),P.hasMany(f),f.belongsTo(P),O.hasMany(f),f.belongsTo(O),function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(w||(w={}));class b{static write(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.NONE,"",e,t,r)}))}static error(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.ERROR,"error",e,t,r)}))}static info(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.INFO,"info",e,t,r)}))}static success(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.ERROR,"success",e,t,r)}))}static warning(e,t,r){return y(this,void 0,void 0,(function*(){yield b.writeRaw(w.WARNING,"warning",e,t,r)}))}static writeConsole(e,r,s){const o=t.dateFormat(new Date,"%H:%M:%S");console.log(">",e,r+" ".repeat(10-r.length),"","|",o,"|",s)}static writeRaw(e,t,r,s,o){return y(this,void 0,void 0,(function*(){o&&b.writeConsole(e,t,r),R&&(yield E.create({type:t,source:s,message:r}).catch((()=>null)))}))}}const S=e=>n.existsSync(e)?n.readFileSync(e):void 0,q={http:S(m.API_HTTP_CRT),token:S(m.API_TOKEN_CRT)},x={http:S(m.API_HTTP_KEY),token:S(m.API_TOKEN_KEY)};class C{static error(e){b.error(e.message,"api.token",m.API_CONSOLE_ERROR)}static sign(e){return x.token?{token:i.sign(e,x.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static user(e){return y(this,void 0,void 0,(function*(){const{error:t,decode:r}=C.verify(e);if(t)return{error:t};if(r){const{id:e,secret:t}=r;if(e&&r){const r=yield P.findOne({where:{id:e,state:!0}}).catch(C.error);if(r){const e=yield v.findOne({where:{secret:t,userId:r.id}}).catch(C.error);if(e){const t=Date.now();if(t>e.timestamp)return e.logout=t,yield e.save(),{error:"Expired token"};if(e.timestamp=t+6e4*m.API_TOKEN_LIFETIME,!e.logout)return yield e.save(),{auth:e,user:r}}}return{error:"Access denied"}}}return{error:"Invalid token"}}))}static verify(e){if(!q.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:i.verify(e,q.token)}}catch(e){return{error:"Invalid Token"}}}}class D extends e.Application{constructor(e){super(e,{cert:q.http,cross:m.API_HTTP_CROSS,hybrid:m.API_HTTP_HYBRID,key:x.http,path:"/api",port:m.API_HTTP_PORT,public:m.API_HTTP_PUBLIC})}error(e,t){b.info(e.message,t,m.API_CONSOLE_ERROR)}log(e,t){b.info(e,t,!0)}listen(){const e=Object.create(null,{listen:{get:()=>super.listen}});return y(this,void 0,void 0,(function*(){yield R.sync(),yield e.listen.call(this),m.API_WEBSOCKET_START&&this.server&&(this._webSocket=new r.Server({server:this.server,verifyClient:(e,t)=>t(m.API_WEBSOCKET_START)}),this._webSocket.on("connection",((e,r)=>y(this,void 0,void 0,(function*(){r.url||(r.url="");const s=r.url.length<=1?"":r.url.replace(/\//g,".");let o;e.on("message",(t=>y(this,void 0,void 0,(function*(){if(o)try{const n=JSON.parse(t);this.emit("ws.message"+s,{data:n,message:t,req:r,user:o,ws:e})}catch(n){this.emit("ws.message"+s,{message:t,req:r,user:o,ws:e})}else{const{user:n}=yield C.user(t.toString());n&&(o=n,this.emit("ws.connection"+s,{req:r,user:o,ws:e}))}o||e.close()})))),e.on("close",(()=>{o&&this.emit("ws.close"+s,{user:o,ws:e})})),yield t.sleep(2e3),o||e.close()})))))}))}websocket(){return this._webSocket}}class j{static all(){return y(this,void 0,void 0,(function*(){const e=yield T.findAll().catch(j.error),t={};return e&&e.forEach((e=>{t[e.key]=e.value})),t}))}static del(e){return y(this,void 0,void 0,(function*(){return((yield T.destroy({where:{key:e}}).catch(j.error))||0)>0}))}static error(e){b.error(e.message,"api.config",m.API_CONSOLE_ERROR)}static get(e){return y(this,void 0,void 0,(function*(){const t=yield T.findOne({where:{key:e}}).catch(j.error);return t&&t.value||""}))}static set(e,t){return y(this,void 0,void 0,(function*(){const[r]=(yield T.findOrCreate({where:{key:e}}).catch(j.error))||[];r&&(r.value=t,yield r.save().catch(j.error))}))}}class N{static all(e,t){return y(this,void 0,void 0,(function*(){return yield I.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:_,required:!0,include:[{model:O,required:!0,where:{state:!0},include:[{model:f,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{b.error(e.message,"api.permission",m.API_CONSOLE_ERROR)}))}))}static get(e){return y(this,void 0,void 0,(function*(){const t=yield N.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return y(this,void 0,void 0,(function*(){const r=yield N.all(e,{name:t});return!!r&&r.length>0}))}}const F=e.parameterFactory((({req:e})=>e.auth)),B=e.parameterFactory((({req:e})=>e.user)),G=(e,r)=>{const s=t.uuidv4()+"."+r;return n.existsSync(u.join(e,s))?G(e,r):s};class M extends t.EventEmitter{auth(t,r,s,o,n){return y(this,void 0,void 0,(function*(){const{auth:i,error:a,user:d}=yield C.user(s);return a?e.Responses.error(t,a):i&&d?(o&&(i.useragent=o),yield i.save(),r.auth=i,r.user=d,n()):e.Responses.error(t,"Internal Server Error")}))}error(e){b.error(e.message,"api.controller",m.API_CONSOLE_ERROR)}name(){return"api"}permission(t,r,s,o){return y(this,void 0,void 0,(function*(){return r?(yield N.is(r,o))?s():e.Responses.error(t,"Unauthorized access"):e.Responses.unauthorized(t,"Access denied")}))}read(e,t,r,s){return this.permission(e,t,r,(s||this.name())+".read")}upload(t,r,s,o){const n=(null==o?void 0:o.path)||m.API_UPLOAD_TEMP,i=l.diskStorage({destination:(e,t,r)=>r(null,n),filename:(e,t,r)=>y(this,void 0,void 0,(function*(){return r(null,G(n,d.extension(t.mimetype)||"bin"))}))}),a=1e6*((null==o?void 0:o.size)||m.API_UPLOAD_SIZE),u=l({storage:i,fileFilter(e,t,r){var s;return y(this,void 0,void 0,(function*(){const e=null===(s=null==o?void 0:o.types)||void 0===s?void 0:s.indexOf(t.mimetype);return void 0!==e&&e<0?r(new Error("File type not allowed")):r(null,!0)}))},limits:{fileSize:a}}),c=(null==o?void 0:o.count)||m.API_UPLOAD_COUNT,p=(null==o?void 0:o.field)||m.API_UPLOAD_FIELD;u.array(p,c)(r,t,(r=>r?e.Responses.error(t,r.message):s()))}validation(r,s,o,n){return y(this,void 0,void 0,(function*(){const{error:i,value:a}=yield t.Validation.object(n).validateAsync(s.body);return i?e.Responses.validation(r,i):(s.body=a,o())}))}write(e,t,r,s){return this.permission(e,t,r,(s||this.name())+".write")}}c([p(0,e.Res()),p(1,e.Req()),p(2,e.Headers(m.API_TOKEN_HEADER)),p(3,e.Headers("user-agent")),p(4,e.Next()),g("design:type",Function),g("design:paramtypes",[Object,Object,String,String,Function]),g("design:returntype",Promise)],M.prototype,"auth",null),c([p(0,e.Res()),p(1,B()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,P,Function,String]),g("design:returntype",Promise)],M.prototype,"permission",null),c([p(0,e.Res()),p(1,B()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,P,Function,String]),g("design:returntype",void 0)],M.prototype,"read",null),c([p(0,e.Res()),p(1,e.Req()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function,Object]),g("design:returntype",void 0)],M.prototype,"upload",null),c([p(0,e.Res()),p(1,e.Req()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function,Object]),g("design:returntype",Promise)],M.prototype,"validation",null),c([p(0,e.Res()),p(1,B()),p(2,e.Next()),p(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,P,Function,String]),g("design:returntype",void 0)],M.prototype,"write",null),exports.AuthController=class extends M{constructor(){super(...arguments),this.attributes=["id","name","email","username","avatar"]}login(r,s,o,n){return y(this,void 0,void 0,(function*(){yield t.sleep(m.API_SLEEP_AUTH);const{username:i,password:d}=s.body,l=yield P.findOne({where:{username:i}}).catch(this.error);if(!l)return n.emit("auth.failure",{req:s}),e.Responses.notfound(r,"Username not found");if(!l.state)return n.emit("auth.failure",{req:s}),e.Responses.error(r,"Username is disabled");const u=a.SHA256(d).toString();if(l.password!=u)return n.emit("auth.failure",{req:s}),e.Responses.error(r,"Invalid password");const c=l.id,p=t.uniqueID(),{error:g,token:y}=C.sign({id:c,secret:p});if(g)return n.emit("auth.failure",{req:s}),e.Responses.error(r,g);if(y){const t=Date.now(),n=t+6e4*m.API_TOKEN_LIFETIME,i=yield v.create({login:t,secret:p,timestamp:n,useragent:o,userId:c}).catch(this.error);if(i)return this.emit("auth.login",{auth:i,req:s,user:l}),e.Responses.data(r,{token:y})}return n.emit("auth.failure",{req:s}),e.Responses.error(r,"Internal Server Error")}))}logout(t,r,s,o,n){return y(this,void 0,void 0,(function*(){return s&&o&&!s.logout?(s.logout=Date.now(),s.timestamp=s.logout,yield s.save(),n.emit("auth.logout",{auth:s,req:r,user:o}),e.Responses.success(t,"Disconcerted")):e.Responses.unauthorized(t,"Access denied")}))}user(r,s){return y(this,void 0,void 0,(function*(){const o=s.user;if(!o)return e.Responses.unauthorized(r,"Access denied");const n=yield N.all(o);if(n){const s=n.map((e=>e.name));return e.Responses.data(r,Object.assign(Object.assign({},t.allowedObject(this.attributes,o.toJSON())),{permissions:s}))}return e.Responses.error(r,"Internal Server Error")}))}},c([e.Post("/login"),e.Middleware("validation",{username:t.Validation.string().min(4).required(),password:t.Validation.string().min(5).required()}),p(0,e.Res()),p(1,e.Req()),p(2,e.Headers("user-agent")),p(3,e.App()),g("design:type",Function),g("design:paramtypes",[Object,Object,String,D]),g("design:returntype",Promise)],exports.AuthController.prototype,"login",null),c([e.Get("/logout"),e.Middleware("auth"),p(0,e.Res()),p(1,e.Req()),p(2,F()),p(3,B()),p(4,e.App()),g("design:type",Function),g("design:paramtypes",[Object,Object,v,P,D]),g("design:returntype",Promise)],exports.AuthController.prototype,"logout",null),c([e.Get(),e.Middleware("auth"),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.AuthController.prototype,"user",null),exports.AuthController=c([e.Controller("/auth")],exports.AuthController),exports.ForgotController=class extends M{check(r,s){return y(this,void 0,void 0,(function*(){const{token:o}=s.body,n=yield this.findOne(o);return n&&n.user?(n.token=t.uniqueID(),yield n.save(),e.Responses.data(r,{token:n.token})):e.Responses.notfound(r,"User not found")}))}forgot(r,s){return y(this,void 0,void 0,(function*(){const{username:o}=s.body;yield t.sleep(m.API_SLEEP_FORGOT);const n=yield P.findOne({where:{username:o}}).catch(this.error);if(!n)return e.Responses.notfound(r,"User not found");const i=t.uniqueID(),a=Date.now()+6e4*m.API_TOKEN_LIFETIME,d=yield A.create({token:i,timestamp:a,state:!0,userId:n.id});return this.emit("forgot",{forgot:d,req:s,user:n}),e.Responses.success(r,"OK")}))}reset(t,r){return y(this,void 0,void 0,(function*(){const{token:s,password:o}=r.body,n=yield this.findOne(s);return n?(n.state=!1,yield n.save().catch(this.error),n.user.password=a.SHA256(o).toString(),yield n.user.save().catch(this.error),this.emit("forgot.reset",{req:r,user:n.user}),e.Responses.success(t,"OK")):e.Responses.notfound(t,"User not found")}))}findOne(e){return y(this,void 0,void 0,(function*(){return yield A.findOne({where:{token:e,state:!0},include:[{model:P,required:!0}]}).catch(this.error)}))}},c([e.Get("/check"),e.Middleware("validation",{token:t.Validation.string().required()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.ForgotController.prototype,"check",null),c([e.Get(),e.Middleware("validation",{username:t.Validation.string().min(4).required()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.ForgotController.prototype,"forgot",null),c([e.Get("/reset"),e.Middleware("validation",{token:t.Validation.string().required(),password:t.Validation.string().min(5).required()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.ForgotController.prototype,"reset",null),exports.ForgotController=c([e.Controller("/forgot")],exports.ForgotController);class L extends M{add(t,r,s){return y(this,void 0,void 0,(function*(){const o=yield this.model().create(t.body,s||{}).catch(this.error);if(o){const t=o.id;return e.Responses.data(r,{id:t}),t}return e.Responses.error(r,"Internal Server Error"),0}))}all(r,o,n,i){var a,d,l,u,c;return y(this,void 0,void 0,(function*(){const p=this.model(),g=Object.assign({},n||{});g.where=Object.assign({},g.where||{});const y=null===(a=r.query.limit)||void 0===a?void 0:a.toString();y&&(g.limit=parseInt(y));const m=null===(d=r.query.offset)||void 0===d?void 0:d.toString();m&&(g.offset=parseInt(m));const h=Object.keys(p.getAttributes()),R=[],v=null===(l=r.query.asc)||void 0===l?void 0:l.toString();v&&v.length&&v.split(",").forEach((e=>{h.indexOf(e)>=0&&R.push([e,"ASC"])}));const A=null===(u=r.query.desc)||void 0===u?void 0:u.toString();A&&A.length&&A.split(",").forEach((e=>{h.indexOf(e)>=0&&R.push([e,"DESC"])})),R.length&&(g.order=R);const O=[],I=t.isArray(g.attributes)?g.attributes:h,_=null===(c=r.query.search)||void 0===c?void 0:c.toString();I.forEach((e=>{var o;if(t.isString(e)&&(_&&_.length&&O.push({[e]:{[s.Op.like]:`%${_}%`}}),"search_"+e in r.query)){const t=null===(o=r.query["search_"+e])||void 0===o?void 0:o.toString();t&&t.length&&O.push({[e]:{[s.Op.like]:`%${t}%`}})}})),O.length&&(g.where=Object.assign(Object.assign({},g.where),{[s.Op.or]:[...O]}));const P=yield p.count(Object.assign(Object.assign({},g),{col:h[0]})).catch(this.error),f=yield p.findAll(g).catch(this.error);if(f)return e.Responses.data(o,{count:P,records:i?i(f):f}),f;e.Responses.error(o,"Internal Server Error")}))}del(t,r,s){return y(this,void 0,void 0,(function*(){const{id:o}=t.params;if(!o)return e.Responses.error(r,"Internal Server Error"),0;const n=yield this.model().destroy(Object.assign(Object.assign({},s||{}),{where:{id:o}})).catch(this.error);return n?(e.Responses.success(r,"OK"),n):(e.Responses.notfound(r,"Record not found"),0)}))}error(e){e.sql?b.error(e.message+"\n"+e.sql,"api.controller.sql",m.API_CONSOLE_ERROR):super.error(e)}get(t,r,s,o){return y(this,void 0,void 0,(function*(){const n=Object.assign({},s||{});n.where=n.where?Object.assign({},n.where):{};const{id:i}=t.params,a=yield this.model().findByPk(i,n).catch(this.error);if(a)return e.Responses.data(r,o?o(a):a.toJSON()),a;null!==a?e.Responses.error(r,"Internal Server Error"):e.Responses.notfound(r,"Record not found")}))}name(){return this.model().tableName}set(t,r,s){return y(this,void 0,void 0,(function*(){const{id:o}=t.params,[n]=(yield this.model().update(t.body,Object.assign(Object.assign({},s||{}),{where:Object.assign(Object.assign({},(s||{}).where),{id:o})})).catch(this.error))||[];return n?(e.Responses.success(r,"OK"),!0):(e.Responses.success(r,"Record not changed"),!1)}))}}class k extends L{create(){return{}}recordAdd(e,t){this.add(e,t)}recordAll(e,t){this.all(e,t)}recordDel(e,t){this.del(e,t)}recordGet(e,t){this.get(e,t)}recordSet(e,t){this.set(e,t)}update(){return{}}validationAdd(e,t,r){this.validation(t,e,r,this.create())}validationSet(e,t,r){this.validation(t,e,r,this.update())}}c([e.Post(),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validationAdd"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordAdd",null),c([e.Get(),e.Middleware("auth"),e.Middleware("read"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordAll",null),c([e.Delete("/:id"),e.Middleware("auth"),e.Middleware("write"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordDel",null),c([e.Get("/:id"),e.Middleware("auth"),e.Middleware("read"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordGet",null),c([e.Put("/:id"),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validationSet"),p(0,e.Req()),p(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"recordSet",null),c([p(0,e.Req()),p(1,e.Res()),p(2,e.Next()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function]),g("design:returntype",void 0)],k.prototype,"validationAdd",null),c([p(0,e.Req()),p(1,e.Res()),p(2,e.Next()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function]),g("design:returntype",void 0)],k.prototype,"validationSet",null),exports.GroupController=class extends k{model(){return O}create(){return{name:t.Validation.string().required(),description:t.Validation.string().empty(""),state:t.Validation.boolean().parse().required()}}update(){return{name:t.Validation.string().empty(),description:t.Validation.string().empty(),state:t.Validation.boolean().parse().empty()}}},exports.GroupController=c([e.Controller("/groups")],exports.GroupController),exports.GroupRouteController=class extends L{model(){return _}groupRouteAll(e,t,r){return y(this,void 0,void 0,(function*(){return this.all(t,e,{where:{groupId:r},include:[{model:I,required:!0}]},(e=>e.map((e=>e.route))))}))}groupRouteSet(r,s,o){return y(this,void 0,void 0,(function*(){const n=yield O.findByPk(s,{attributes:["id"]}).catch(this.error);if(n){const t=n.id;if(yield _.destroy({where:{groupId:t}}),o){let e=0;for(let r=0;r<o.length;r++)e=yield I.count({where:{id:o[r]}}),e&&(yield _.create({groupId:t,routeId:o[r]}))}return e.Responses.success(r,"OK")}return t.isNull(n)?e.Responses.notfound(r,"Record not found"):e.Responses.error(r,"Internal Server Error")}))}},c([e.Get("/:id/routes"),e.Middleware("auth"),e.Middleware("read","routes"),p(0,e.Res()),p(1,e.Req()),p(2,e.Params("id")),g("design:type",Function),g("design:paramtypes",[Object,Object,String]),g("design:returntype",Promise)],exports.GroupRouteController.prototype,"groupRouteAll",null),c([e.Put("/:id/groups"),e.Middleware("auth"),e.Middleware("write","groups"),e.Middleware("validation",{routes:t.Validation.array(t.Validation.number().parse())}),p(0,e.Res()),p(1,e.Params("id")),p(2,e.Body("routes")),g("design:type",Function),g("design:paramtypes",[Object,String,Array]),g("design:returntype",Promise)],exports.GroupRouteController.prototype,"groupRouteSet",null),exports.GroupRouteController=c([e.Controller("/groups")],exports.GroupRouteController),exports.LogsController=class extends L{model(){return E}logsAll(e,t){return y(this,void 0,void 0,(function*(){const{source:r,type:s}=t.query,o=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return this.all(t,e,{where:o,order:[["created","DESC"]]})}))}},c([e.Get(),e.Middleware("auth"),e.Middleware("read"),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.LogsController.prototype,"logsAll",null),exports.LogsController=c([e.Controller("/logs")],exports.LogsController);class U extends s.Model{}U.init({token:s.DataTypes.STRING,timestamp:s.DataTypes.BIGINT,state:s.DataTypes.BOOLEAN},{sequelize:R,modelName:m.API_TABLE_PREFIX+"registry",timestamps:!0,createdAt:"created",updatedAt:"updated"}),exports.RegisterController=class extends M{confirm(t,r){return y(this,void 0,void 0,(function*(){const s=yield U.findOne({where:{token:r,state:!0},include:[{model:P,required:!0}]}).catch(this.error);return s?(s.user.state=!0,yield s.user.save().catch(this.error),this.emit("user.confirm",{user:s.user}),e.Responses.success(t,"OK")):e.Responses.notfound(t,"User not found")}))}register(r,s,o,n){return y(this,void 0,void 0,(function*(){yield t.sleep(m.API_SLEEP_REGISTRY);const s=yield P.findOne({where:{username:n}}).catch(this.error);if(s)return e.Responses.error(r,"Invalid Username");if(!t.isNull(s))return e.Responses.error(r,"Internal Server Error");const i=yield P.create(Object.assign(Object.assign({},o),{state:!1}));return this.emit("user.register",{user:i}),e.Responses.success(r,"OK")}))}},c([e.Get("/confirm"),e.Middleware("validation",{token:t.Validation.string().required()}),p(0,e.Res()),p(1,e.Body("token")),g("design:type",Function),g("design:paramtypes",[Object,String]),g("design:returntype",Promise)],exports.RegisterController.prototype,"confirm",null),c([e.Get(),e.Middleware("validation",{name:t.Validation.string().required(),email:t.Validation.string().email().required(),username:t.Validation.string().min(4).required(),password:t.Validation.string().min(5).required()}),p(0,e.Res()),p(1,e.Req()),p(2,e.Body()),p(3,e.Body("username")),g("design:type",Function),g("design:paramtypes",[Object,Object,Object,String]),g("design:returntype",Promise)],exports.RegisterController.prototype,"register",null),exports.RegisterController=c([e.Controller("/register")],exports.RegisterController),exports.RouteController=class extends k{model(){return I}create(){return{name:t.Validation.string().required(),description:t.Validation.string().empty(""),state:t.Validation.boolean().parse().required()}}update(){return{name:t.Validation.string().empty(),description:t.Validation.string().empty(),state:t.Validation.boolean().empty()}}},exports.RouteController=c([e.Controller("/routes")],exports.RouteController),exports.SetupController=class extends M{setup(r){return y(this,void 0,void 0,(function*(){if(0==(yield P.count())){const e={description:"",state:!0},r=yield P.create(Object.assign({name:"Admin",email:"admin@localhost",username:"admin",password:"8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",avatar:""},e)),s=yield O.create(Object.assign({name:"admin"},e));yield f.create({userId:r.id,groupId:s.id});const o=["read","write"],n=["users","groups","routes"];yield t.forEachSeries(n,(r=>y(this,void 0,void 0,(function*(){yield t.forEachSeries(o,(t=>y(this,void 0,void 0,(function*(){const o=r+"."+t,n=yield I.create(Object.assign({name:o},e));yield _.create({groupId:s.id,routeId:n.id})}))))}))));const i=yield I.create(Object.assign({name:"logs.read"},e));yield _.create({groupId:s.id,routeId:i.id})}return e.Responses.success(r,"OK")}))}},c([e.Get(),p(0,e.Res()),g("design:type",Function),g("design:paramtypes",[Object]),g("design:returntype",Promise)],exports.SetupController.prototype,"setup",null),exports.SetupController=c([e.Controller("/setup")],exports.SetupController),exports.UserController=class extends L{constructor(){super(...arguments),this.attributes=["id","name","email","username","avatar","description","state","created","updated"]}model(){return P}userAdd(e,t){return y(this,void 0,void 0,(function*(){return t.body.password=a.SHA256(t.body.password).toString(),yield this.add(t,e)}))}userAll(e,t){return y(this,void 0,void 0,(function*(){return this.all(t,e,{attributes:this.attributes})}))}userDel(t,r,s,o){return y(this,void 0,void 0,(function*(){return s&&s.id.toString()!=o?this.del(r,t):e.Responses.error(t,"Internal Server Error")}))}userGet(e,t){return y(this,void 0,void 0,(function*(){return this.get(t,e,{attributes:this.attributes})}))}userSet(e,t){return y(this,void 0,void 0,(function*(){return t.body.password&&(t.body.password=a.SHA256(t.body.password).toString()),this.set(t,e)}))}},c([e.Post(),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validation",{name:t.Validation.string().required(),email:t.Validation.string().email().required(),username:t.Validation.string().min(4).required(),password:t.Validation.string().min(5).required(),description:t.Validation.string().required(),state:t.Validation.boolean().parse().required()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userAdd",null),c([e.Get(),e.Middleware("auth"),e.Middleware("read"),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userAll",null),c([e.Delete("/:id"),e.Middleware("auth"),e.Middleware("write"),p(0,e.Res()),p(1,e.Req()),p(2,B()),p(3,e.Params("id")),g("design:type",Function),g("design:paramtypes",[Object,Object,P,String]),g("design:returntype",Promise)],exports.UserController.prototype,"userDel",null),c([e.Get("/:id"),e.Middleware("auth"),e.Middleware("read"),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userGet",null),c([e.Put("/:id"),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validation",{name:t.Validation.string().empty(),email:t.Validation.string().email().empty(),username:t.Validation.string().min(4).empty(),password:t.Validation.string().min(5).empty(),description:t.Validation.string().empty(),state:t.Validation.boolean().parse().empty()}),p(0,e.Res()),p(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userSet",null),exports.UserController=c([e.Controller("/users")],exports.UserController),exports.UserGroupController=class extends L{model(){return f}userGroupsAll(e,t,r){return y(this,void 0,void 0,(function*(){return this.all(t,e,{where:{userId:r},include:[{model:O,required:!0}]},(e=>e.map((e=>e.group))))}))}userGroupsSet(r,s,o){return y(this,void 0,void 0,(function*(){const n=yield P.findByPk(s,{attributes:["id"]}).catch(this.error);if(n){if(yield f.destroy({where:{userId:n.id}}),o){let e=0;for(let t=0;t<o.length;t++)e=yield O.count({where:{id:o[t]}}),e&&(yield f.create({userId:n.id,groupId:o[t]}))}return e.Responses.success(r,"OK")}return t.isNull(n)?e.Responses.notfound(r,"Record not found"):e.Responses.error(r,"Internal Server Error")}))}},c([e.Get("/:id/groups"),e.Middleware("auth"),e.Middleware("read","groups"),p(0,e.Res()),p(1,e.Req()),p(2,e.Params("id")),g("design:type",Function),g("design:paramtypes",[Object,Object,String]),g("design:returntype",Promise)],exports.UserGroupController.prototype,"userGroupsAll",null),c([e.Put("/:id/groups"),e.Middleware("auth"),e.Middleware("write","groups"),e.Middleware("validation",{groups:t.Validation.array(t.Validation.number().parse())}),p(0,e.Res()),p(1,e.Params("id")),p(2,e.Body("groups")),g("design:type",Function),g("design:paramtypes",[Object,String,Array]),g("design:returntype",Promise)],exports.UserGroupController.prototype,"userGroupsSet",null),exports.UserGroupController=c([e.Controller("/users")],exports.UserGroupController),exports.Application=D,exports.Auth=v,exports.Config=j,exports.Configs=T,exports.ControllerBase=M,exports.CrudController=k,exports.Database=h,exports.Env=m,exports.Forgot=A,exports.Group=O,exports.GroupRoute=_,exports.Log=b,exports.Logs=E,exports.ModelController=L,exports.Permission=N,exports.ReqAuth=F,exports.ReqUser=B,exports.Route=I,exports.Token=C,exports.User=P,exports.UserGroup=f,exports.crt=q,exports.key=x,exports.sequelize=R;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @andrewcaires/api v3.0.1
2
+ * @andrewcaires/api v3.0.2
3
3
  * Simple api for small applications using express, jsonwebtoken, sequelize and websocket
4
4
  * (c) 2023 Andrew Caires
5
5
  * @license: MIT
@@ -137,26 +137,26 @@ declare class ForgotController extends ControllerBase {
137
137
  type FnRecord<M> = (records: M) => any;
138
138
  type FnRecords<M> = (records: Array<M>) => Array<any>;
139
139
  declare abstract class ModelController<M extends Model<M>> extends ControllerBase {
140
- protected add(req: Request, res: Response, options?: CreateOptions<Attributes<M>>): Promise<_andrewcaires_express.ResponseJson>;
141
- protected all(req: Request, res: Response, options?: FindOptions<Attributes<M>>, fn?: FnRecords<M>): Promise<_andrewcaires_express.ResponseJson>;
142
- protected del(req: Request, res: Response, options?: FindOptions<Attributes<M>>): Promise<_andrewcaires_express.ResponseJson>;
140
+ protected add(req: Request, res: Response, options?: CreateOptions<Attributes<M>>): Promise<number>;
141
+ protected all(req: Request, res: Response, options?: FindOptions<Attributes<M>>, fn?: FnRecords<M>): Promise<Array<M> | void>;
142
+ protected del(req: Request, res: Response, options?: FindOptions<Attributes<M>>): Promise<number>;
143
143
  error(error: any): void;
144
- protected get(req: Request, res: Response, options?: FindOptions<Attributes<M>>, fn?: FnRecord<M>): Promise<_andrewcaires_express.ResponseJson>;
144
+ protected get(req: Request, res: Response, options?: FindOptions<Attributes<M>>, fn?: FnRecord<M>): Promise<M | undefined>;
145
145
  abstract model(): ModelStatic<M>;
146
146
  protected name(): string;
147
- protected set(req: Request, res: Response, options?: UpdateOptions<Attributes<M>>): Promise<_andrewcaires_express.ResponseJson>;
147
+ protected set(req: Request, res: Response, options?: UpdateOptions<Attributes<M>>): Promise<boolean>;
148
148
  }
149
149
 
150
150
  declare abstract class CrudController<M extends Model<M>> extends ModelController<M> {
151
151
  create(): TypeObject<ValidationBase>;
152
- recordAdd(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
153
- recordAll(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
154
- recordDel(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
155
- recordGet(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
156
- recordSet(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
152
+ recordAdd(req: Request, res: Response): void;
153
+ recordAll(req: Request, res: Response): void;
154
+ recordDel(req: Request, res: Response): void;
155
+ recordGet(req: Request, res: Response): void;
156
+ recordSet(req: Request, res: Response): void;
157
157
  update(): TypeObject<ValidationBase>;
158
- validationAdd(req: Request, res: Response, next: NextFunction): Promise<void | _andrewcaires_express.ResponseJson>;
159
- validationSet(req: Request, res: Response, next: NextFunction): Promise<void | _andrewcaires_express.ResponseJson>;
158
+ validationAdd(req: Request, res: Response, next: NextFunction): void;
159
+ validationSet(req: Request, res: Response, next: NextFunction): void;
160
160
  }
161
161
 
162
162
  declare class GroupController extends CrudController<Group> {
@@ -167,13 +167,13 @@ declare class GroupController extends CrudController<Group> {
167
167
 
168
168
  declare class GroupRouteController extends ModelController<GroupRoute> {
169
169
  model(): typeof GroupRoute;
170
- groupRouteAll(res: Response, req: Request, groupId: string): Promise<_andrewcaires_express.ResponseJson>;
170
+ groupRouteAll(res: Response, req: Request, groupId: string): Promise<void | GroupRoute[]>;
171
171
  groupRouteSet(res: Response, id: string, routes: Array<number>): Promise<_andrewcaires_express.ResponseJson>;
172
172
  }
173
173
 
174
174
  declare class LogsController extends ModelController<Logs> {
175
175
  model(): typeof Logs;
176
- protected logsAll(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
176
+ protected logsAll(res: Response, req: Request): Promise<void | Logs[]>;
177
177
  }
178
178
 
179
179
  declare class RegisterController extends ControllerBase {
@@ -194,16 +194,16 @@ declare class SetupController extends ControllerBase {
194
194
  declare class UserController extends ModelController<User> {
195
195
  private readonly attributes;
196
196
  model(): typeof User;
197
- userAdd(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
198
- protected userAll(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
199
- protected userDel(res: Response, req: Request, user: User, id: string): Promise<_andrewcaires_express.ResponseJson>;
200
- protected userGet(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
201
- protected userSet(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
197
+ userAdd(res: Response, req: Request): Promise<number>;
198
+ protected userAll(res: Response, req: Request): Promise<void | User[]>;
199
+ protected userDel(res: Response, req: Request, user: User, id: string): Promise<number | _andrewcaires_express.ResponseJson>;
200
+ protected userGet(res: Response, req: Request): Promise<User | undefined>;
201
+ protected userSet(res: Response, req: Request): Promise<boolean>;
202
202
  }
203
203
 
204
204
  declare class UserGroupController extends ModelController<UserGroup> {
205
205
  model(): typeof UserGroup;
206
- userGroupsAll(res: Response, req: Request, userId: string): Promise<_andrewcaires_express.ResponseJson>;
206
+ userGroupsAll(res: Response, req: Request, userId: string): Promise<void | UserGroup[]>;
207
207
  userGroupsSet(res: Response, id: string, groups: Array<number>): Promise<_andrewcaires_express.ResponseJson>;
208
208
  }
209
209
 
package/dist/index.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @andrewcaires/api v3.0.1
2
+ * @andrewcaires/api v3.0.2
3
3
  * Simple api for small applications using express, jsonwebtoken, sequelize and websocket
4
4
  * (c) 2023 Andrew Caires
5
5
  * @license: MIT
6
6
  */
7
- import{Application as e,parameterFactory as t,Res as r,Req as n,Headers as i,Next as s,Argument as o,Responses as d,Post as a,Middleware as u,App as c,Get as l,Controller as p,Delete as m,Put as g,Params as y,Body as h}from"@andrewcaires/express";import{toBool as v,dateFormat as O,sleep as _,EventEmitter as I,Validation as A,uuidv4 as f,uniqueID as P,allowedObject as E,isArray as b,isString as T,isNull as S,forEachSeries as R}from"@andrewcaires/utils.js";import w from"ws";import{Sequelize as j,DataTypes as N,Model as q,Op as F}from"sequelize";import{config as D}from"dotenv";import{existsSync as L,readFileSync as B}from"fs";import{sign as k,verify as G}from"jsonwebtoken";import{SHA256 as C}from"crypto-js";import x from"mime-types";import K from"multer";import{join as U}from"path";function H(e,t,r,n){var i,s=arguments.length,o=s<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,r):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,r,n);else for(var d=e.length-1;d>=0;d--)(i=e[d])&&(o=(s<3?i(o):s>3?i(t,r,o):i(t,r))||o);return s>3&&o&&Object.defineProperty(t,r,o),o}function z(e,t){return function(r,n){t(r,n,e)}}function M(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function X(e,t,r,n){return new(r||(r=Promise))((function(i,s){function o(e){try{a(n.next(e))}catch(e){s(e)}}function d(e){try{a(n.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,d)}a((n=n.apply(e,t||[])).next())}))}D();class Y{}Y.API_CONSOLE_ERROR=v(process.env.API_CONSOLE_ERROR||"false"),Y.API_DB_DATABASE=process.env.API_DB_DATABASE||"",Y.API_DB_HOST=process.env.API_DB_HOST||"127.0.0.1",Y.API_DB_PASSWORD=process.env.API_DB_PASSWORD||"",Y.API_DB_PORT=parseInt(process.env.API_DB_PORT||"3306"),Y.API_DB_TYPE=process.env.API_DB_TYPE||"",Y.API_DB_USERNAME=process.env.API_DB_USERNAME||"root",Y.API_DB_LOG=v(process.env.API_DB_LOG||"false"),Y.API_TABLE_PREFIX=process.env.API_TABLE_PREFIX||"",Y.API_HTTP_CRT=process.env.API_HTTP_CRT||"",Y.API_HTTP_KEY=process.env.API_HTTP_KEY||"",Y.API_HTTP_PORT=parseInt(process.env.API_HTTP_PORT||"3000"),Y.API_HTTP_PUBLIC=process.env.API_HTTP_PUBLIC||"",Y.API_HTTP_CROSS=v(process.env.API_HTTP_CROSS||"false"),Y.API_HTTP_HYBRID=v(process.env.API_HTTP_HYBRID||"false"),Y.API_SLEEP_AUTH=parseInt(process.env.API_SLEEP_AUTH||"1000"),Y.API_SLEEP_FORGOT=parseInt(process.env.API_SLEEP_FORGOT||"5000"),Y.API_SLEEP_REGISTRY=parseInt(process.env.API_SLEEP_REGISTRY||"5000"),Y.API_TOKEN_CRT=process.env.API_TOKEN_CRT||"",Y.API_TOKEN_KEY=process.env.API_TOKEN_KEY||"",Y.API_TOKEN_HEADER=process.env.API_TOKEN_HEADER||"authorization",Y.API_TOKEN_LIFETIME=parseInt(process.env.API_TOKEN_LIFETIME||"15"),Y.API_UPLOAD_COUNT=parseInt(process.env.API_UPLOAD_COUNT||"1"),Y.API_UPLOAD_FIELD=process.env.API_UPLOAD_FIELD||"upload",Y.API_UPLOAD_SIZE=parseInt(process.env.API_UPLOAD_SIZE||"2"),Y.API_UPLOAD_TEMP=process.env.API_UPLOAD_TEMP||"./temp",Y.API_WEBSOCKET_START=v(process.env.API_WEBSOCKET_START||"false");class W{static connect(e){const t="connect_"+Y.API_DB_TYPE.toLowerCase();if(t in W)return W[t](e);throw new Error("No database is connected to this API")}static connect_mariadb(e){return new j(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mariadb",logging:Y.API_DB_LOG,define:{timestamps:!1}})}static connect_memory(){return new j("sqlite::memory:",{logging:Y.API_DB_LOG,define:{timestamps:!1}})}static connect_mysql(e){return new j(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mysql",logging:Y.API_DB_LOG,define:{timestamps:!1}})}static connect_postgres(e){return new j(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"postgres",logging:Y.API_DB_LOG,define:{timestamps:!1}})}static connect_sqlite(e){return new j({dialect:"sqlite",storage:e.database,logging:Y.API_DB_LOG,define:{timestamps:!1}})}}const J=W.connect({database:Y.API_DB_DATABASE,username:Y.API_DB_USERNAME,password:Y.API_DB_PASSWORD,hostname:Y.API_DB_HOST,hostport:Y.API_DB_PORT});class Z extends q{}Z.init({login:N.BIGINT,logout:N.BIGINT,secret:N.STRING,timestamp:N.BIGINT,useragent:N.STRING},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"auth",timestamps:!0,createdAt:"created",updatedAt:"updated"});class $ extends q{}$.init({token:N.STRING,timestamp:N.BIGINT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"forgot",timestamps:!0,createdAt:"created",updatedAt:"updated"});class Q extends q{}Q.init({name:N.STRING,description:N.TEXT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"group",timestamps:!0,createdAt:"created",updatedAt:"updated"});class V extends q{}V.init({name:N.STRING,description:N.TEXT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"route",timestamps:!0,createdAt:"created",updatedAt:"updated"});class ee extends q{}ee.init({},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"groups_routes",timestamps:!0,createdAt:"created",updatedAt:!1}),ee.removeAttribute("id");class te extends q{}te.init({name:N.STRING,email:N.STRING,username:N.STRING,password:N.STRING,avatar:N.STRING,description:N.TEXT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"user",timestamps:!0,createdAt:"created",updatedAt:"updated"});class re extends q{}re.init({},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"users_groups",timestamps:!0,createdAt:"created",updatedAt:!1}),re.removeAttribute("id");class ne extends q{}ne.init({key:N.STRING,value:N.STRING},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),ne.removeAttribute("id");class ie extends q{}var se;ie.init({type:N.STRING,source:N.STRING,message:N.TEXT},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),te.hasMany(Z),Z.belongsTo(te),te.hasMany($),$.belongsTo(te),Q.hasMany(ee),ee.belongsTo(Q),V.hasMany(ee),ee.belongsTo(V),te.hasMany(re),re.belongsTo(te),Q.hasMany(re),re.belongsTo(Q),function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(se||(se={}));class oe{static write(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.NONE,"",e,t,r)}))}static error(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.ERROR,"error",e,t,r)}))}static info(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.INFO,"info",e,t,r)}))}static success(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.ERROR,"success",e,t,r)}))}static warning(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.WARNING,"warning",e,t,r)}))}static writeConsole(e,t,r){const n=O(new Date,"%H:%M:%S");console.log(">",e,t+" ".repeat(10-t.length),"","|",n,"|",r)}static writeRaw(e,t,r,n,i){return X(this,void 0,void 0,(function*(){i&&oe.writeConsole(e,t,r),J&&(yield ie.create({type:t,source:n,message:r}).catch((()=>null)))}))}}const de=e=>L(e)?B(e):void 0,ae={http:de(Y.API_HTTP_CRT),token:de(Y.API_TOKEN_CRT)},ue={http:de(Y.API_HTTP_KEY),token:de(Y.API_TOKEN_KEY)};class ce{static error(e){oe.error(e.message,"api.token",Y.API_CONSOLE_ERROR)}static sign(e){return ue.token?{token:k(e,ue.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static user(e){return X(this,void 0,void 0,(function*(){const{error:t,decode:r}=ce.verify(e);if(t)return{error:t};if(r){const{id:e,secret:t}=r;if(e&&r){const r=yield te.findOne({where:{id:e,state:!0}}).catch(ce.error);if(r){const e=yield Z.findOne({where:{secret:t,userId:r.id}}).catch(ce.error);if(e){const t=Date.now();if(t>e.timestamp)return e.logout=t,yield e.save(),{error:"Expired token"};if(e.timestamp=t+6e4*Y.API_TOKEN_LIFETIME,!e.logout)return yield e.save(),{auth:e,user:r}}}return{error:"Access denied"}}}return{error:"Invalid token"}}))}static verify(e){if(!ae.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:G(e,ae.token)}}catch(e){return{error:"Invalid Token"}}}}class le extends e{constructor(e){super(e,{cert:ae.http,cross:Y.API_HTTP_CROSS,hybrid:Y.API_HTTP_HYBRID,key:ue.http,path:"/api",port:Y.API_HTTP_PORT,public:Y.API_HTTP_PUBLIC})}error(e,t){oe.info(e.message,t,Y.API_CONSOLE_ERROR)}log(e,t){oe.info(e,t,!0)}listen(){const e=Object.create(null,{listen:{get:()=>super.listen}});return X(this,void 0,void 0,(function*(){yield J.sync(),yield e.listen.call(this),Y.API_WEBSOCKET_START&&this.server&&(this._webSocket=new w.Server({server:this.server,verifyClient:(e,t)=>t(Y.API_WEBSOCKET_START)}),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 n;e.on("message",(i=>X(this,void 0,void 0,(function*(){if(n)try{const s=JSON.parse(i);this.emit("ws.message"+r,{data:s,message:i,req:t,user:n,ws:e})}catch(s){this.emit("ws.message"+r,{message:i,req:t,user:n,ws:e})}else{const{user:s}=yield ce.user(i.toString());s&&(n=s,this.emit("ws.connection"+r,{req:t,user:n,ws:e}))}n||e.close()})))),e.on("close",(()=>{n&&this.emit("ws.close"+r,{user:n,ws:e})})),yield _(2e3),n||e.close()})))))}))}websocket(){return this._webSocket}}class pe{static all(){return X(this,void 0,void 0,(function*(){const e=yield ne.findAll().catch(pe.error),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 ne.destroy({where:{key:e}}).catch(pe.error))||0)>0}))}static error(e){oe.error(e.message,"api.config",Y.API_CONSOLE_ERROR)}static get(e){return X(this,void 0,void 0,(function*(){const t=yield ne.findOne({where:{key:e}}).catch(pe.error);return t&&t.value||""}))}static set(e,t){return X(this,void 0,void 0,(function*(){const[r]=(yield ne.findOrCreate({where:{key:e}}).catch(pe.error))||[];r&&(r.value=t,yield r.save().catch(pe.error))}))}}class me{static all(e,t){return X(this,void 0,void 0,(function*(){return yield V.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:ee,required:!0,include:[{model:Q,required:!0,where:{state:!0},include:[{model:re,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{oe.error(e.message,"api.permission",Y.API_CONSOLE_ERROR)}))}))}static get(e){return X(this,void 0,void 0,(function*(){const t=yield me.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return X(this,void 0,void 0,(function*(){const r=yield me.all(e,{name:t});return!!r&&r.length>0}))}}const ge=t((({req:e})=>e.auth)),ye=t((({req:e})=>e.user)),he=(e,t)=>{const r=f()+"."+t;return L(U(e,r))?he(e,t):r};class ve extends I{auth(e,t,r,n,i){return X(this,void 0,void 0,(function*(){const{auth:s,error:o,user:a}=yield ce.user(r);return o?d.error(e,o):s&&a?(n&&(s.useragent=n),yield s.save(),t.auth=s,t.user=a,i()):d.error(e,"Internal Server Error")}))}error(e){oe.error(e.message,"api.controller",Y.API_CONSOLE_ERROR)}name(){return"api"}permission(e,t,r,n){return X(this,void 0,void 0,(function*(){return t?(yield me.is(t,n))?r():d.error(e,"Unauthorized access"):d.unauthorized(e,"Access denied")}))}read(e,t,r,n){return this.permission(e,t,r,(n||this.name())+".read")}upload(e,t,r,n){const i=(null==n?void 0:n.path)||Y.API_UPLOAD_TEMP,s=K.diskStorage({destination:(e,t,r)=>r(null,i),filename:(e,t,r)=>X(this,void 0,void 0,(function*(){return r(null,he(i,x.extension(t.mimetype)||"bin"))}))}),o=1e6*((null==n?void 0:n.size)||Y.API_UPLOAD_SIZE),a=K({storage:s,fileFilter(e,t,r){var i;return X(this,void 0,void 0,(function*(){const e=null===(i=null==n?void 0:n.types)||void 0===i?void 0:i.indexOf(t.mimetype);return void 0!==e&&e<0?r(new Error("File type not allowed")):r(null,!0)}))},limits:{fileSize:o}}),u=(null==n?void 0:n.count)||Y.API_UPLOAD_COUNT,c=(null==n?void 0:n.field)||Y.API_UPLOAD_FIELD;a.array(c,u)(t,e,(t=>t?d.error(e,t.message):r()))}validation(e,t,r,n){return X(this,void 0,void 0,(function*(){const{error:i,value:s}=yield A.object(n).validateAsync(t.body);return i?d.validation(e,i):(t.body=s,r())}))}write(e,t,r,n){return this.permission(e,t,r,(n||this.name())+".write")}}H([z(0,r()),z(1,n()),z(2,i(Y.API_TOKEN_HEADER)),z(3,i("user-agent")),z(4,s()),M("design:type",Function),M("design:paramtypes",[Object,Object,String,String,Function]),M("design:returntype",Promise)],ve.prototype,"auth",null),H([z(0,r()),z(1,ye()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,te,Function,String]),M("design:returntype",Promise)],ve.prototype,"permission",null),H([z(0,r()),z(1,ye()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,te,Function,String]),M("design:returntype",void 0)],ve.prototype,"read",null),H([z(0,r()),z(1,n()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,Object,Function,Object]),M("design:returntype",void 0)],ve.prototype,"upload",null),H([z(0,r()),z(1,n()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,Object,Function,Object]),M("design:returntype",Promise)],ve.prototype,"validation",null),H([z(0,r()),z(1,ye()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,te,Function,String]),M("design:returntype",void 0)],ve.prototype,"write",null);let Oe=class extends ve{constructor(){super(...arguments),this.attributes=["id","name","email","username","avatar"]}login(e,t,r,n){return X(this,void 0,void 0,(function*(){yield _(Y.API_SLEEP_AUTH);const{username:i,password:s}=t.body,o=yield te.findOne({where:{username:i}}).catch(this.error);if(!o)return n.emit("auth.failure",{req:t}),d.notfound(e,"Username not found");if(!o.state)return n.emit("auth.failure",{req:t}),d.error(e,"Username is disabled");const a=C(s).toString();if(o.password!=a)return n.emit("auth.failure",{req:t}),d.error(e,"Invalid password");const u=o.id,c=P(),{error:l,token:p}=ce.sign({id:u,secret:c});if(l)return n.emit("auth.failure",{req:t}),d.error(e,l);if(p){const n=Date.now(),i=n+6e4*Y.API_TOKEN_LIFETIME,s=yield Z.create({login:n,secret:c,timestamp:i,useragent:r,userId:u}).catch(this.error);if(s)return this.emit("auth.login",{auth:s,req:t,user:o}),d.data(e,{token:p})}return n.emit("auth.failure",{req:t}),d.error(e,"Internal Server Error")}))}logout(e,t,r,n,i){return X(this,void 0,void 0,(function*(){return r&&n&&!r.logout?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),i.emit("auth.logout",{auth:r,req:t,user:n}),d.success(e,"Disconcerted")):d.unauthorized(e,"Access denied")}))}user(e,t){return X(this,void 0,void 0,(function*(){const r=t.user;if(!r)return d.unauthorized(e,"Access denied");const n=yield me.all(r);if(n){const t=n.map((e=>e.name));return d.data(e,Object.assign(Object.assign({},E(this.attributes,r.toJSON())),{permissions:t}))}return d.error(e,"Internal Server Error")}))}};H([a("/login"),u("validation",{username:A.string().min(4).required(),password:A.string().min(5).required()}),z(0,r()),z(1,n()),z(2,i("user-agent")),z(3,c()),M("design:type",Function),M("design:paramtypes",[Object,Object,String,le]),M("design:returntype",Promise)],Oe.prototype,"login",null),H([l("/logout"),u("auth"),z(0,r()),z(1,n()),z(2,ge()),z(3,ye()),z(4,c()),M("design:type",Function),M("design:paramtypes",[Object,Object,Z,te,le]),M("design:returntype",Promise)],Oe.prototype,"logout",null),H([l(),u("auth"),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],Oe.prototype,"user",null),Oe=H([p("/auth")],Oe);let _e=class extends ve{check(e,t){return X(this,void 0,void 0,(function*(){const{token:r}=t.body,n=yield this.findOne(r);return n&&n.user?(n.token=P(),yield n.save(),d.data(e,{token:n.token})):d.notfound(e,"User not found")}))}forgot(e,t){return X(this,void 0,void 0,(function*(){const{username:r}=t.body;yield _(Y.API_SLEEP_FORGOT);const n=yield te.findOne({where:{username:r}}).catch(this.error);if(!n)return d.notfound(e,"User not found");const i=P(),s=Date.now()+6e4*Y.API_TOKEN_LIFETIME,o=yield $.create({token:i,timestamp:s,state:!0,userId:n.id});return this.emit("forgot",{forgot:o,req:t,user:n}),d.success(e,"OK")}))}reset(e,t){return X(this,void 0,void 0,(function*(){const{token:r,password:n}=t.body,i=yield this.findOne(r);return i?(i.state=!1,yield i.save().catch(this.error),i.user.password=C(n).toString(),yield i.user.save().catch(this.error),this.emit("forgot.reset",{req:t,user:i.user}),d.success(e,"OK")):d.notfound(e,"User not found")}))}findOne(e){return X(this,void 0,void 0,(function*(){return yield $.findOne({where:{token:e,state:!0},include:[{model:te,required:!0}]}).catch(this.error)}))}};H([l("/check"),u("validation",{token:A.string().required()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],_e.prototype,"check",null),H([l(),u("validation",{username:A.string().min(4).required()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],_e.prototype,"forgot",null),H([l("/reset"),u("validation",{token:A.string().required(),password:A.string().min(5).required()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],_e.prototype,"reset",null),_e=H([p("/forgot")],_e);class Ie extends ve{add(e,t,r){return X(this,void 0,void 0,(function*(){const n=yield this.model().create(e.body,r||{}).catch(this.error);return n?d.data(t,{id:n.id}):d.error(t,"Internal Server Error")}))}all(e,t,r,n){var i,s,o,a,u;return X(this,void 0,void 0,(function*(){const c=this.model(),l=Object.assign({},r||{});l.where=Object.assign({},l.where||{});const p=null===(i=e.query.limit)||void 0===i?void 0:i.toString();p&&(l.limit=parseInt(p));const m=null===(s=e.query.offset)||void 0===s?void 0:s.toString();m&&(l.offset=parseInt(m));const g=Object.keys(c.getAttributes()),y=[],h=null===(o=e.query.asc)||void 0===o?void 0:o.toString();h&&h.length&&h.split(",").forEach((e=>{g.indexOf(e)>=0&&y.push([e,"ASC"])}));const v=null===(a=e.query.desc)||void 0===a?void 0:a.toString();v&&v.length&&v.split(",").forEach((e=>{g.indexOf(e)>=0&&y.push([e,"DESC"])})),y.length&&(l.order=y);const O=[],_=b(l.attributes)?l.attributes:g,I=null===(u=e.query.search)||void 0===u?void 0:u.toString();_.forEach((t=>{var r;if(T(t)&&(I&&I.length&&O.push({[t]:{[F.like]:`%${I}%`}}),"search_"+t in e.query)){const n=null===(r=e.query["search_"+t])||void 0===r?void 0:r.toString();n&&n.length&&O.push({[t]:{[F.like]:`%${n}%`}})}})),O.length&&(l.where=Object.assign(Object.assign({},l.where),{[F.or]:[...O]}));const A=yield c.count(Object.assign(Object.assign({},l),{col:g[0]})).catch(this.error),f=yield c.findAll(l).catch(this.error);return f?d.data(t,{count:A,records:n?n(f):f}):d.error(t,"Internal Server Error")}))}del(e,t,r){return X(this,void 0,void 0,(function*(){const{id:n}=e.params;if(!n)return d.error(t,"Internal Server Error");return(yield this.model().destroy(Object.assign(Object.assign({},r||{}),{where:{id:n}})).catch(this.error))?d.success(t,"OK"):d.notfound(t,"Record not found")}))}error(e){e.sql?oe.error(e.message+"\n"+e.sql,"api.controller.sql",Y.API_CONSOLE_ERROR):super.error(e)}get(e,t,r,n){return X(this,void 0,void 0,(function*(){const i=Object.assign({},r||{});i.where=i.where?Object.assign({},i.where):{};const{id:s}=e.params,o=yield this.model().findByPk(s,i).catch(this.error);return o?d.data(t,n?n(o):o.toJSON()):null===o?d.notfound(t,"Record not found"):d.error(t,"Internal Server Error")}))}name(){return this.model().tableName}set(e,t,r){return X(this,void 0,void 0,(function*(){const{id:n}=e.params,[i]=(yield this.model().update(e.body,Object.assign(Object.assign({},r||{}),{where:Object.assign(Object.assign({},(r||{}).where),{id:n})})).catch(this.error))||[];return i?d.success(t,"OK"):d.success(t,"Record not changed")}))}}class Ae extends Ie{create(){return{}}recordAdd(e,t){return this.add(e,t)}recordAll(e,t){return this.all(e,t)}recordDel(e,t){return this.del(e,t)}recordGet(e,t){return this.get(e,t)}recordSet(e,t){return this.set(e,t)}update(){return{}}validationAdd(e,t,r){return this.validation(t,e,r,this.create())}validationSet(e,t,r){return this.validation(t,e,r,this.update())}}H([a(),u("auth"),u("write"),u("validationAdd"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],Ae.prototype,"recordAdd",null),H([l(),u("auth"),u("read"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],Ae.prototype,"recordAll",null),H([m("/:id"),u("auth"),u("write"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],Ae.prototype,"recordDel",null),H([l("/:id"),u("auth"),u("read"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],Ae.prototype,"recordGet",null),H([g("/:id"),u("auth"),u("write"),u("validationSet"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],Ae.prototype,"recordSet",null),H([z(0,n()),z(1,r()),z(2,s()),M("design:type",Function),M("design:paramtypes",[Object,Object,Function]),M("design:returntype",void 0)],Ae.prototype,"validationAdd",null),H([z(0,n()),z(1,r()),z(2,s()),M("design:type",Function),M("design:paramtypes",[Object,Object,Function]),M("design:returntype",void 0)],Ae.prototype,"validationSet",null);let fe=class extends Ae{model(){return Q}create(){return{name:A.string().required(),description:A.string().empty(""),state:A.boolean().parse().required()}}update(){return{name:A.string().empty(),description:A.string().empty(),state:A.boolean().parse().empty()}}};fe=H([p("/groups")],fe);let Pe=class extends Ie{model(){return ee}groupRouteAll(e,t,r){return X(this,void 0,void 0,(function*(){return this.all(t,e,{where:{groupId:r},include:[{model:V,required:!0}]},(e=>e.map((e=>e.route))))}))}groupRouteSet(e,t,r){return X(this,void 0,void 0,(function*(){const n=yield Q.findByPk(t,{attributes:["id"]}).catch(this.error);if(n){const t=n.id;if(yield ee.destroy({where:{groupId:t}}),r){let e=0;for(let n=0;n<r.length;n++)e=yield V.count({where:{id:r[n]}}),e&&(yield ee.create({groupId:t,routeId:r[n]}))}return d.success(e,"OK")}return S(n)?d.notfound(e,"Record not found"):d.error(e,"Internal Server Error")}))}};H([l("/:id/routes"),u("auth"),u("read","routes"),z(0,r()),z(1,n()),z(2,y("id")),M("design:type",Function),M("design:paramtypes",[Object,Object,String]),M("design:returntype",Promise)],Pe.prototype,"groupRouteAll",null),H([g("/:id/groups"),u("auth"),u("write","groups"),u("validation",{routes:A.array(A.number().parse())}),z(0,r()),z(1,y("id")),z(2,h("routes")),M("design:type",Function),M("design:paramtypes",[Object,String,Array]),M("design:returntype",Promise)],Pe.prototype,"groupRouteSet",null),Pe=H([p("/groups")],Pe);let Ee=class extends Ie{model(){return ie}logsAll(e,t){return X(this,void 0,void 0,(function*(){const{source:r,type:n}=t.query,i=r&&n?{source:r,type:n}:r?{source:r}:n?{type:n}:{};return this.all(t,e,{where:i,order:[["created","DESC"]]})}))}};H([l(),u("auth"),u("read"),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],Ee.prototype,"logsAll",null),Ee=H([p("/logs")],Ee);class be extends q{}be.init({token:N.STRING,timestamp:N.BIGINT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"registry",timestamps:!0,createdAt:"created",updatedAt:"updated"});let Te=class extends ve{confirm(e,t){return X(this,void 0,void 0,(function*(){const r=yield be.findOne({where:{token:t,state:!0},include:[{model:te,required:!0}]}).catch(this.error);return r?(r.user.state=!0,yield r.user.save().catch(this.error),this.emit("user.confirm",{user:r.user}),d.success(e,"OK")):d.notfound(e,"User not found")}))}register(e,t,r,n){return X(this,void 0,void 0,(function*(){yield _(Y.API_SLEEP_REGISTRY);const t=yield te.findOne({where:{username:n}}).catch(this.error);if(t)return d.error(e,"Invalid Username");if(!S(t))return d.error(e,"Internal Server Error");const i=yield te.create(Object.assign(Object.assign({},r),{state:!1}));return this.emit("user.register",{user:i}),d.success(e,"OK")}))}};H([l("/confirm"),u("validation",{token:A.string().required()}),z(0,r()),z(1,h("token")),M("design:type",Function),M("design:paramtypes",[Object,String]),M("design:returntype",Promise)],Te.prototype,"confirm",null),H([l(),u("validation",{name:A.string().required(),email:A.string().email().required(),username:A.string().min(4).required(),password:A.string().min(5).required()}),z(0,r()),z(1,n()),z(2,h()),z(3,h("username")),M("design:type",Function),M("design:paramtypes",[Object,Object,Object,String]),M("design:returntype",Promise)],Te.prototype,"register",null),Te=H([p("/register")],Te);let Se=class extends Ae{model(){return V}create(){return{name:A.string().required(),description:A.string().empty(""),state:A.boolean().parse().required()}}update(){return{name:A.string().empty(),description:A.string().empty(),state:A.boolean().empty()}}};Se=H([p("/routes")],Se);let Re=class extends ve{setup(e){return X(this,void 0,void 0,(function*(){if(0==(yield te.count())){const e={description:"",state:!0},t=yield te.create(Object.assign({name:"Admin",email:"admin@localhost",username:"admin",password:"8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",avatar:""},e)),r=yield Q.create(Object.assign({name:"admin"},e));yield re.create({userId:t.id,groupId:r.id});const n=["read","write"],i=["users","groups","routes"];yield R(i,(t=>X(this,void 0,void 0,(function*(){yield R(n,(n=>X(this,void 0,void 0,(function*(){const i=t+"."+n,s=yield V.create(Object.assign({name:i},e));yield ee.create({groupId:r.id,routeId:s.id})}))))}))));const s=yield V.create(Object.assign({name:"logs.read"},e));yield ee.create({groupId:r.id,routeId:s.id})}return d.success(e,"OK")}))}};H([l(),z(0,r()),M("design:type",Function),M("design:paramtypes",[Object]),M("design:returntype",Promise)],Re.prototype,"setup",null),Re=H([p("/setup")],Re);let we=class extends Ie{constructor(){super(...arguments),this.attributes=["id","name","email","username","avatar","description","state","created","updated"]}model(){return te}userAdd(e,t){return X(this,void 0,void 0,(function*(){return t.body.password=C(t.body.password).toString(),yield this.add(t,e)}))}userAll(e,t){return X(this,void 0,void 0,(function*(){return this.all(t,e,{attributes:this.attributes})}))}userDel(e,t,r,n){return X(this,void 0,void 0,(function*(){return r&&r.id.toString()!=n?this.del(t,e):d.error(e,"Internal Server Error")}))}userGet(e,t){return X(this,void 0,void 0,(function*(){return this.get(t,e,{attributes:this.attributes})}))}userSet(e,t){return X(this,void 0,void 0,(function*(){return t.body.password&&(t.body.password=C(t.body.password).toString()),this.set(t,e)}))}};H([a(),u("auth"),u("write"),u("validation",{name:A.string().required(),email:A.string().email().required(),username:A.string().min(4).required(),password:A.string().min(5).required(),description:A.string().required(),state:A.boolean().parse().required()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],we.prototype,"userAdd",null),H([l(),u("auth"),u("read"),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],we.prototype,"userAll",null),H([m("/:id"),u("auth"),u("write"),z(0,r()),z(1,n()),z(2,ye()),z(3,y("id")),M("design:type",Function),M("design:paramtypes",[Object,Object,te,String]),M("design:returntype",Promise)],we.prototype,"userDel",null),H([l("/:id"),u("auth"),u("read"),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],we.prototype,"userGet",null),H([g("/:id"),u("auth"),u("write"),u("validation",{name:A.string().empty(),email:A.string().email().empty(),username:A.string().min(4).empty(),password:A.string().min(5).empty(),description:A.string().empty(),state:A.boolean().parse().empty()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],we.prototype,"userSet",null),we=H([p("/users")],we);let je=class extends Ie{model(){return re}userGroupsAll(e,t,r){return X(this,void 0,void 0,(function*(){return this.all(t,e,{where:{userId:r},include:[{model:Q,required:!0}]},(e=>e.map((e=>e.group))))}))}userGroupsSet(e,t,r){return X(this,void 0,void 0,(function*(){const n=yield te.findByPk(t,{attributes:["id"]}).catch(this.error);if(n){if(yield re.destroy({where:{userId:n.id}}),r){let e=0;for(let t=0;t<r.length;t++)e=yield Q.count({where:{id:r[t]}}),e&&(yield re.create({userId:n.id,groupId:r[t]}))}return d.success(e,"OK")}return S(n)?d.notfound(e,"Record not found"):d.error(e,"Internal Server Error")}))}};H([l("/:id/groups"),u("auth"),u("read","groups"),z(0,r()),z(1,n()),z(2,y("id")),M("design:type",Function),M("design:paramtypes",[Object,Object,String]),M("design:returntype",Promise)],je.prototype,"userGroupsAll",null),H([g("/:id/groups"),u("auth"),u("write","groups"),u("validation",{groups:A.array(A.number().parse())}),z(0,r()),z(1,y("id")),z(2,h("groups")),M("design:type",Function),M("design:paramtypes",[Object,String,Array]),M("design:returntype",Promise)],je.prototype,"userGroupsSet",null),je=H([p("/users")],je);export{le as Application,Z as Auth,Oe as AuthController,pe as Config,ne as Configs,ve as ControllerBase,Ae as CrudController,W as Database,Y as Env,$ as Forgot,_e as ForgotController,Q as Group,fe as GroupController,ee as GroupRoute,Pe as GroupRouteController,oe as Log,ie as Logs,Ee as LogsController,Ie as ModelController,me as Permission,Te as RegisterController,ge as ReqAuth,ye as ReqUser,V as Route,Se as RouteController,Re as SetupController,ce as Token,te as User,we as UserController,re as UserGroup,je as UserGroupController,ae as crt,ue as key,J as sequelize};
7
+ import{Application as e,parameterFactory as t,Res as r,Req as n,Headers as i,Next as s,Argument as o,Responses as d,Post as a,Middleware as u,App as c,Get as l,Controller as p,Delete as m,Put as g,Params as y,Body as h}from"@andrewcaires/express";import{toBool as v,dateFormat as O,sleep as _,EventEmitter as I,Validation as f,uuidv4 as A,uniqueID as P,allowedObject as E,isArray as b,isString as T,isNull as S,forEachSeries as R}from"@andrewcaires/utils.js";import w from"ws";import{Sequelize as j,DataTypes as N,Model as q,Op as F}from"sequelize";import{config as D}from"dotenv";import{existsSync as L,readFileSync as B}from"fs";import{sign as k,verify as G}from"jsonwebtoken";import{SHA256 as C}from"crypto-js";import x from"mime-types";import K from"multer";import{join as U}from"path";function H(e,t,r,n){var i,s=arguments.length,o=s<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,r):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,r,n);else for(var d=e.length-1;d>=0;d--)(i=e[d])&&(o=(s<3?i(o):s>3?i(t,r,o):i(t,r))||o);return s>3&&o&&Object.defineProperty(t,r,o),o}function z(e,t){return function(r,n){t(r,n,e)}}function M(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function X(e,t,r,n){return new(r||(r=Promise))((function(i,s){function o(e){try{a(n.next(e))}catch(e){s(e)}}function d(e){try{a(n.throw(e))}catch(e){s(e)}}function a(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,d)}a((n=n.apply(e,t||[])).next())}))}D();class Y{}Y.API_CONSOLE_ERROR=v(process.env.API_CONSOLE_ERROR||"false"),Y.API_DB_DATABASE=process.env.API_DB_DATABASE||"",Y.API_DB_HOST=process.env.API_DB_HOST||"127.0.0.1",Y.API_DB_PASSWORD=process.env.API_DB_PASSWORD||"",Y.API_DB_PORT=parseInt(process.env.API_DB_PORT||"3306"),Y.API_DB_TYPE=process.env.API_DB_TYPE||"",Y.API_DB_USERNAME=process.env.API_DB_USERNAME||"root",Y.API_DB_LOG=v(process.env.API_DB_LOG||"false"),Y.API_TABLE_PREFIX=process.env.API_TABLE_PREFIX||"",Y.API_HTTP_CRT=process.env.API_HTTP_CRT||"",Y.API_HTTP_KEY=process.env.API_HTTP_KEY||"",Y.API_HTTP_PORT=parseInt(process.env.API_HTTP_PORT||"3000"),Y.API_HTTP_PUBLIC=process.env.API_HTTP_PUBLIC||"",Y.API_HTTP_CROSS=v(process.env.API_HTTP_CROSS||"false"),Y.API_HTTP_HYBRID=v(process.env.API_HTTP_HYBRID||"false"),Y.API_SLEEP_AUTH=parseInt(process.env.API_SLEEP_AUTH||"1000"),Y.API_SLEEP_FORGOT=parseInt(process.env.API_SLEEP_FORGOT||"5000"),Y.API_SLEEP_REGISTRY=parseInt(process.env.API_SLEEP_REGISTRY||"5000"),Y.API_TOKEN_CRT=process.env.API_TOKEN_CRT||"",Y.API_TOKEN_KEY=process.env.API_TOKEN_KEY||"",Y.API_TOKEN_HEADER=process.env.API_TOKEN_HEADER||"authorization",Y.API_TOKEN_LIFETIME=parseInt(process.env.API_TOKEN_LIFETIME||"15"),Y.API_UPLOAD_COUNT=parseInt(process.env.API_UPLOAD_COUNT||"1"),Y.API_UPLOAD_FIELD=process.env.API_UPLOAD_FIELD||"upload",Y.API_UPLOAD_SIZE=parseInt(process.env.API_UPLOAD_SIZE||"2"),Y.API_UPLOAD_TEMP=process.env.API_UPLOAD_TEMP||"./temp",Y.API_WEBSOCKET_START=v(process.env.API_WEBSOCKET_START||"false");class W{static connect(e){const t="connect_"+Y.API_DB_TYPE.toLowerCase();if(t in W)return W[t](e);throw new Error("No database is connected to this API")}static connect_mariadb(e){return new j(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mariadb",logging:Y.API_DB_LOG,define:{timestamps:!1}})}static connect_memory(){return new j("sqlite::memory:",{logging:Y.API_DB_LOG,define:{timestamps:!1}})}static connect_mysql(e){return new j(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mysql",logging:Y.API_DB_LOG,define:{timestamps:!1}})}static connect_postgres(e){return new j(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"postgres",logging:Y.API_DB_LOG,define:{timestamps:!1}})}static connect_sqlite(e){return new j({dialect:"sqlite",storage:e.database,logging:Y.API_DB_LOG,define:{timestamps:!1}})}}const J=W.connect({database:Y.API_DB_DATABASE,username:Y.API_DB_USERNAME,password:Y.API_DB_PASSWORD,hostname:Y.API_DB_HOST,hostport:Y.API_DB_PORT});class Z extends q{}Z.init({login:N.BIGINT,logout:N.BIGINT,secret:N.STRING,timestamp:N.BIGINT,useragent:N.STRING},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"auth",timestamps:!0,createdAt:"created",updatedAt:"updated"});class $ extends q{}$.init({token:N.STRING,timestamp:N.BIGINT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"forgot",timestamps:!0,createdAt:"created",updatedAt:"updated"});class Q extends q{}Q.init({name:N.STRING,description:N.TEXT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"group",timestamps:!0,createdAt:"created",updatedAt:"updated"});class V extends q{}V.init({name:N.STRING,description:N.TEXT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"route",timestamps:!0,createdAt:"created",updatedAt:"updated"});class ee extends q{}ee.init({},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"groups_routes",timestamps:!0,createdAt:"created",updatedAt:!1}),ee.removeAttribute("id");class te extends q{}te.init({name:N.STRING,email:N.STRING,username:N.STRING,password:N.STRING,avatar:N.STRING,description:N.TEXT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"user",timestamps:!0,createdAt:"created",updatedAt:"updated"});class re extends q{}re.init({},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"users_groups",timestamps:!0,createdAt:"created",updatedAt:!1}),re.removeAttribute("id");class ne extends q{}ne.init({key:N.STRING,value:N.STRING},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),ne.removeAttribute("id");class ie extends q{}var se;ie.init({type:N.STRING,source:N.STRING,message:N.TEXT},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),te.hasMany(Z),Z.belongsTo(te),te.hasMany($),$.belongsTo(te),Q.hasMany(ee),ee.belongsTo(Q),V.hasMany(ee),ee.belongsTo(V),te.hasMany(re),re.belongsTo(te),Q.hasMany(re),re.belongsTo(Q),function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(se||(se={}));class oe{static write(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.NONE,"",e,t,r)}))}static error(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.ERROR,"error",e,t,r)}))}static info(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.INFO,"info",e,t,r)}))}static success(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.ERROR,"success",e,t,r)}))}static warning(e,t,r){return X(this,void 0,void 0,(function*(){yield oe.writeRaw(se.WARNING,"warning",e,t,r)}))}static writeConsole(e,t,r){const n=O(new Date,"%H:%M:%S");console.log(">",e,t+" ".repeat(10-t.length),"","|",n,"|",r)}static writeRaw(e,t,r,n,i){return X(this,void 0,void 0,(function*(){i&&oe.writeConsole(e,t,r),J&&(yield ie.create({type:t,source:n,message:r}).catch((()=>null)))}))}}const de=e=>L(e)?B(e):void 0,ae={http:de(Y.API_HTTP_CRT),token:de(Y.API_TOKEN_CRT)},ue={http:de(Y.API_HTTP_KEY),token:de(Y.API_TOKEN_KEY)};class ce{static error(e){oe.error(e.message,"api.token",Y.API_CONSOLE_ERROR)}static sign(e){return ue.token?{token:k(e,ue.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static user(e){return X(this,void 0,void 0,(function*(){const{error:t,decode:r}=ce.verify(e);if(t)return{error:t};if(r){const{id:e,secret:t}=r;if(e&&r){const r=yield te.findOne({where:{id:e,state:!0}}).catch(ce.error);if(r){const e=yield Z.findOne({where:{secret:t,userId:r.id}}).catch(ce.error);if(e){const t=Date.now();if(t>e.timestamp)return e.logout=t,yield e.save(),{error:"Expired token"};if(e.timestamp=t+6e4*Y.API_TOKEN_LIFETIME,!e.logout)return yield e.save(),{auth:e,user:r}}}return{error:"Access denied"}}}return{error:"Invalid token"}}))}static verify(e){if(!ae.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:G(e,ae.token)}}catch(e){return{error:"Invalid Token"}}}}class le extends e{constructor(e){super(e,{cert:ae.http,cross:Y.API_HTTP_CROSS,hybrid:Y.API_HTTP_HYBRID,key:ue.http,path:"/api",port:Y.API_HTTP_PORT,public:Y.API_HTTP_PUBLIC})}error(e,t){oe.info(e.message,t,Y.API_CONSOLE_ERROR)}log(e,t){oe.info(e,t,!0)}listen(){const e=Object.create(null,{listen:{get:()=>super.listen}});return X(this,void 0,void 0,(function*(){yield J.sync(),yield e.listen.call(this),Y.API_WEBSOCKET_START&&this.server&&(this._webSocket=new w.Server({server:this.server,verifyClient:(e,t)=>t(Y.API_WEBSOCKET_START)}),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 n;e.on("message",(i=>X(this,void 0,void 0,(function*(){if(n)try{const s=JSON.parse(i);this.emit("ws.message"+r,{data:s,message:i,req:t,user:n,ws:e})}catch(s){this.emit("ws.message"+r,{message:i,req:t,user:n,ws:e})}else{const{user:s}=yield ce.user(i.toString());s&&(n=s,this.emit("ws.connection"+r,{req:t,user:n,ws:e}))}n||e.close()})))),e.on("close",(()=>{n&&this.emit("ws.close"+r,{user:n,ws:e})})),yield _(2e3),n||e.close()})))))}))}websocket(){return this._webSocket}}class pe{static all(){return X(this,void 0,void 0,(function*(){const e=yield ne.findAll().catch(pe.error),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 ne.destroy({where:{key:e}}).catch(pe.error))||0)>0}))}static error(e){oe.error(e.message,"api.config",Y.API_CONSOLE_ERROR)}static get(e){return X(this,void 0,void 0,(function*(){const t=yield ne.findOne({where:{key:e}}).catch(pe.error);return t&&t.value||""}))}static set(e,t){return X(this,void 0,void 0,(function*(){const[r]=(yield ne.findOrCreate({where:{key:e}}).catch(pe.error))||[];r&&(r.value=t,yield r.save().catch(pe.error))}))}}class me{static all(e,t){return X(this,void 0,void 0,(function*(){return yield V.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:ee,required:!0,include:[{model:Q,required:!0,where:{state:!0},include:[{model:re,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{oe.error(e.message,"api.permission",Y.API_CONSOLE_ERROR)}))}))}static get(e){return X(this,void 0,void 0,(function*(){const t=yield me.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return X(this,void 0,void 0,(function*(){const r=yield me.all(e,{name:t});return!!r&&r.length>0}))}}const ge=t((({req:e})=>e.auth)),ye=t((({req:e})=>e.user)),he=(e,t)=>{const r=A()+"."+t;return L(U(e,r))?he(e,t):r};class ve extends I{auth(e,t,r,n,i){return X(this,void 0,void 0,(function*(){const{auth:s,error:o,user:a}=yield ce.user(r);return o?d.error(e,o):s&&a?(n&&(s.useragent=n),yield s.save(),t.auth=s,t.user=a,i()):d.error(e,"Internal Server Error")}))}error(e){oe.error(e.message,"api.controller",Y.API_CONSOLE_ERROR)}name(){return"api"}permission(e,t,r,n){return X(this,void 0,void 0,(function*(){return t?(yield me.is(t,n))?r():d.error(e,"Unauthorized access"):d.unauthorized(e,"Access denied")}))}read(e,t,r,n){return this.permission(e,t,r,(n||this.name())+".read")}upload(e,t,r,n){const i=(null==n?void 0:n.path)||Y.API_UPLOAD_TEMP,s=K.diskStorage({destination:(e,t,r)=>r(null,i),filename:(e,t,r)=>X(this,void 0,void 0,(function*(){return r(null,he(i,x.extension(t.mimetype)||"bin"))}))}),o=1e6*((null==n?void 0:n.size)||Y.API_UPLOAD_SIZE),a=K({storage:s,fileFilter(e,t,r){var i;return X(this,void 0,void 0,(function*(){const e=null===(i=null==n?void 0:n.types)||void 0===i?void 0:i.indexOf(t.mimetype);return void 0!==e&&e<0?r(new Error("File type not allowed")):r(null,!0)}))},limits:{fileSize:o}}),u=(null==n?void 0:n.count)||Y.API_UPLOAD_COUNT,c=(null==n?void 0:n.field)||Y.API_UPLOAD_FIELD;a.array(c,u)(t,e,(t=>t?d.error(e,t.message):r()))}validation(e,t,r,n){return X(this,void 0,void 0,(function*(){const{error:i,value:s}=yield f.object(n).validateAsync(t.body);return i?d.validation(e,i):(t.body=s,r())}))}write(e,t,r,n){return this.permission(e,t,r,(n||this.name())+".write")}}H([z(0,r()),z(1,n()),z(2,i(Y.API_TOKEN_HEADER)),z(3,i("user-agent")),z(4,s()),M("design:type",Function),M("design:paramtypes",[Object,Object,String,String,Function]),M("design:returntype",Promise)],ve.prototype,"auth",null),H([z(0,r()),z(1,ye()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,te,Function,String]),M("design:returntype",Promise)],ve.prototype,"permission",null),H([z(0,r()),z(1,ye()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,te,Function,String]),M("design:returntype",void 0)],ve.prototype,"read",null),H([z(0,r()),z(1,n()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,Object,Function,Object]),M("design:returntype",void 0)],ve.prototype,"upload",null),H([z(0,r()),z(1,n()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,Object,Function,Object]),M("design:returntype",Promise)],ve.prototype,"validation",null),H([z(0,r()),z(1,ye()),z(2,s()),z(3,o()),M("design:type",Function),M("design:paramtypes",[Object,te,Function,String]),M("design:returntype",void 0)],ve.prototype,"write",null);let Oe=class extends ve{constructor(){super(...arguments),this.attributes=["id","name","email","username","avatar"]}login(e,t,r,n){return X(this,void 0,void 0,(function*(){yield _(Y.API_SLEEP_AUTH);const{username:i,password:s}=t.body,o=yield te.findOne({where:{username:i}}).catch(this.error);if(!o)return n.emit("auth.failure",{req:t}),d.notfound(e,"Username not found");if(!o.state)return n.emit("auth.failure",{req:t}),d.error(e,"Username is disabled");const a=C(s).toString();if(o.password!=a)return n.emit("auth.failure",{req:t}),d.error(e,"Invalid password");const u=o.id,c=P(),{error:l,token:p}=ce.sign({id:u,secret:c});if(l)return n.emit("auth.failure",{req:t}),d.error(e,l);if(p){const n=Date.now(),i=n+6e4*Y.API_TOKEN_LIFETIME,s=yield Z.create({login:n,secret:c,timestamp:i,useragent:r,userId:u}).catch(this.error);if(s)return this.emit("auth.login",{auth:s,req:t,user:o}),d.data(e,{token:p})}return n.emit("auth.failure",{req:t}),d.error(e,"Internal Server Error")}))}logout(e,t,r,n,i){return X(this,void 0,void 0,(function*(){return r&&n&&!r.logout?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),i.emit("auth.logout",{auth:r,req:t,user:n}),d.success(e,"Disconcerted")):d.unauthorized(e,"Access denied")}))}user(e,t){return X(this,void 0,void 0,(function*(){const r=t.user;if(!r)return d.unauthorized(e,"Access denied");const n=yield me.all(r);if(n){const t=n.map((e=>e.name));return d.data(e,Object.assign(Object.assign({},E(this.attributes,r.toJSON())),{permissions:t}))}return d.error(e,"Internal Server Error")}))}};H([a("/login"),u("validation",{username:f.string().min(4).required(),password:f.string().min(5).required()}),z(0,r()),z(1,n()),z(2,i("user-agent")),z(3,c()),M("design:type",Function),M("design:paramtypes",[Object,Object,String,le]),M("design:returntype",Promise)],Oe.prototype,"login",null),H([l("/logout"),u("auth"),z(0,r()),z(1,n()),z(2,ge()),z(3,ye()),z(4,c()),M("design:type",Function),M("design:paramtypes",[Object,Object,Z,te,le]),M("design:returntype",Promise)],Oe.prototype,"logout",null),H([l(),u("auth"),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],Oe.prototype,"user",null),Oe=H([p("/auth")],Oe);let _e=class extends ve{check(e,t){return X(this,void 0,void 0,(function*(){const{token:r}=t.body,n=yield this.findOne(r);return n&&n.user?(n.token=P(),yield n.save(),d.data(e,{token:n.token})):d.notfound(e,"User not found")}))}forgot(e,t){return X(this,void 0,void 0,(function*(){const{username:r}=t.body;yield _(Y.API_SLEEP_FORGOT);const n=yield te.findOne({where:{username:r}}).catch(this.error);if(!n)return d.notfound(e,"User not found");const i=P(),s=Date.now()+6e4*Y.API_TOKEN_LIFETIME,o=yield $.create({token:i,timestamp:s,state:!0,userId:n.id});return this.emit("forgot",{forgot:o,req:t,user:n}),d.success(e,"OK")}))}reset(e,t){return X(this,void 0,void 0,(function*(){const{token:r,password:n}=t.body,i=yield this.findOne(r);return i?(i.state=!1,yield i.save().catch(this.error),i.user.password=C(n).toString(),yield i.user.save().catch(this.error),this.emit("forgot.reset",{req:t,user:i.user}),d.success(e,"OK")):d.notfound(e,"User not found")}))}findOne(e){return X(this,void 0,void 0,(function*(){return yield $.findOne({where:{token:e,state:!0},include:[{model:te,required:!0}]}).catch(this.error)}))}};H([l("/check"),u("validation",{token:f.string().required()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],_e.prototype,"check",null),H([l(),u("validation",{username:f.string().min(4).required()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],_e.prototype,"forgot",null),H([l("/reset"),u("validation",{token:f.string().required(),password:f.string().min(5).required()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],_e.prototype,"reset",null),_e=H([p("/forgot")],_e);class Ie extends ve{add(e,t,r){return X(this,void 0,void 0,(function*(){const n=yield this.model().create(e.body,r||{}).catch(this.error);if(n){const e=n.id;return d.data(t,{id:e}),e}return d.error(t,"Internal Server Error"),0}))}all(e,t,r,n){var i,s,o,a,u;return X(this,void 0,void 0,(function*(){const c=this.model(),l=Object.assign({},r||{});l.where=Object.assign({},l.where||{});const p=null===(i=e.query.limit)||void 0===i?void 0:i.toString();p&&(l.limit=parseInt(p));const m=null===(s=e.query.offset)||void 0===s?void 0:s.toString();m&&(l.offset=parseInt(m));const g=Object.keys(c.getAttributes()),y=[],h=null===(o=e.query.asc)||void 0===o?void 0:o.toString();h&&h.length&&h.split(",").forEach((e=>{g.indexOf(e)>=0&&y.push([e,"ASC"])}));const v=null===(a=e.query.desc)||void 0===a?void 0:a.toString();v&&v.length&&v.split(",").forEach((e=>{g.indexOf(e)>=0&&y.push([e,"DESC"])})),y.length&&(l.order=y);const O=[],_=b(l.attributes)?l.attributes:g,I=null===(u=e.query.search)||void 0===u?void 0:u.toString();_.forEach((t=>{var r;if(T(t)&&(I&&I.length&&O.push({[t]:{[F.like]:`%${I}%`}}),"search_"+t in e.query)){const n=null===(r=e.query["search_"+t])||void 0===r?void 0:r.toString();n&&n.length&&O.push({[t]:{[F.like]:`%${n}%`}})}})),O.length&&(l.where=Object.assign(Object.assign({},l.where),{[F.or]:[...O]}));const f=yield c.count(Object.assign(Object.assign({},l),{col:g[0]})).catch(this.error),A=yield c.findAll(l).catch(this.error);if(A)return d.data(t,{count:f,records:n?n(A):A}),A;d.error(t,"Internal Server Error")}))}del(e,t,r){return X(this,void 0,void 0,(function*(){const{id:n}=e.params;if(!n)return d.error(t,"Internal Server Error"),0;const i=yield this.model().destroy(Object.assign(Object.assign({},r||{}),{where:{id:n}})).catch(this.error);return i?(d.success(t,"OK"),i):(d.notfound(t,"Record not found"),0)}))}error(e){e.sql?oe.error(e.message+"\n"+e.sql,"api.controller.sql",Y.API_CONSOLE_ERROR):super.error(e)}get(e,t,r,n){return X(this,void 0,void 0,(function*(){const i=Object.assign({},r||{});i.where=i.where?Object.assign({},i.where):{};const{id:s}=e.params,o=yield this.model().findByPk(s,i).catch(this.error);if(o)return d.data(t,n?n(o):o.toJSON()),o;null!==o?d.error(t,"Internal Server Error"):d.notfound(t,"Record not found")}))}name(){return this.model().tableName}set(e,t,r){return X(this,void 0,void 0,(function*(){const{id:n}=e.params,[i]=(yield this.model().update(e.body,Object.assign(Object.assign({},r||{}),{where:Object.assign(Object.assign({},(r||{}).where),{id:n})})).catch(this.error))||[];return i?(d.success(t,"OK"),!0):(d.success(t,"Record not changed"),!1)}))}}class fe extends Ie{create(){return{}}recordAdd(e,t){this.add(e,t)}recordAll(e,t){this.all(e,t)}recordDel(e,t){this.del(e,t)}recordGet(e,t){this.get(e,t)}recordSet(e,t){this.set(e,t)}update(){return{}}validationAdd(e,t,r){this.validation(t,e,r,this.create())}validationSet(e,t,r){this.validation(t,e,r,this.update())}}H([a(),u("auth"),u("write"),u("validationAdd"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],fe.prototype,"recordAdd",null),H([l(),u("auth"),u("read"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],fe.prototype,"recordAll",null),H([m("/:id"),u("auth"),u("write"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],fe.prototype,"recordDel",null),H([l("/:id"),u("auth"),u("read"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],fe.prototype,"recordGet",null),H([g("/:id"),u("auth"),u("write"),u("validationSet"),z(0,n()),z(1,r()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",void 0)],fe.prototype,"recordSet",null),H([z(0,n()),z(1,r()),z(2,s()),M("design:type",Function),M("design:paramtypes",[Object,Object,Function]),M("design:returntype",void 0)],fe.prototype,"validationAdd",null),H([z(0,n()),z(1,r()),z(2,s()),M("design:type",Function),M("design:paramtypes",[Object,Object,Function]),M("design:returntype",void 0)],fe.prototype,"validationSet",null);let Ae=class extends fe{model(){return Q}create(){return{name:f.string().required(),description:f.string().empty(""),state:f.boolean().parse().required()}}update(){return{name:f.string().empty(),description:f.string().empty(),state:f.boolean().parse().empty()}}};Ae=H([p("/groups")],Ae);let Pe=class extends Ie{model(){return ee}groupRouteAll(e,t,r){return X(this,void 0,void 0,(function*(){return this.all(t,e,{where:{groupId:r},include:[{model:V,required:!0}]},(e=>e.map((e=>e.route))))}))}groupRouteSet(e,t,r){return X(this,void 0,void 0,(function*(){const n=yield Q.findByPk(t,{attributes:["id"]}).catch(this.error);if(n){const t=n.id;if(yield ee.destroy({where:{groupId:t}}),r){let e=0;for(let n=0;n<r.length;n++)e=yield V.count({where:{id:r[n]}}),e&&(yield ee.create({groupId:t,routeId:r[n]}))}return d.success(e,"OK")}return S(n)?d.notfound(e,"Record not found"):d.error(e,"Internal Server Error")}))}};H([l("/:id/routes"),u("auth"),u("read","routes"),z(0,r()),z(1,n()),z(2,y("id")),M("design:type",Function),M("design:paramtypes",[Object,Object,String]),M("design:returntype",Promise)],Pe.prototype,"groupRouteAll",null),H([g("/:id/groups"),u("auth"),u("write","groups"),u("validation",{routes:f.array(f.number().parse())}),z(0,r()),z(1,y("id")),z(2,h("routes")),M("design:type",Function),M("design:paramtypes",[Object,String,Array]),M("design:returntype",Promise)],Pe.prototype,"groupRouteSet",null),Pe=H([p("/groups")],Pe);let Ee=class extends Ie{model(){return ie}logsAll(e,t){return X(this,void 0,void 0,(function*(){const{source:r,type:n}=t.query,i=r&&n?{source:r,type:n}:r?{source:r}:n?{type:n}:{};return this.all(t,e,{where:i,order:[["created","DESC"]]})}))}};H([l(),u("auth"),u("read"),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],Ee.prototype,"logsAll",null),Ee=H([p("/logs")],Ee);class be extends q{}be.init({token:N.STRING,timestamp:N.BIGINT,state:N.BOOLEAN},{sequelize:J,modelName:Y.API_TABLE_PREFIX+"registry",timestamps:!0,createdAt:"created",updatedAt:"updated"});let Te=class extends ve{confirm(e,t){return X(this,void 0,void 0,(function*(){const r=yield be.findOne({where:{token:t,state:!0},include:[{model:te,required:!0}]}).catch(this.error);return r?(r.user.state=!0,yield r.user.save().catch(this.error),this.emit("user.confirm",{user:r.user}),d.success(e,"OK")):d.notfound(e,"User not found")}))}register(e,t,r,n){return X(this,void 0,void 0,(function*(){yield _(Y.API_SLEEP_REGISTRY);const t=yield te.findOne({where:{username:n}}).catch(this.error);if(t)return d.error(e,"Invalid Username");if(!S(t))return d.error(e,"Internal Server Error");const i=yield te.create(Object.assign(Object.assign({},r),{state:!1}));return this.emit("user.register",{user:i}),d.success(e,"OK")}))}};H([l("/confirm"),u("validation",{token:f.string().required()}),z(0,r()),z(1,h("token")),M("design:type",Function),M("design:paramtypes",[Object,String]),M("design:returntype",Promise)],Te.prototype,"confirm",null),H([l(),u("validation",{name:f.string().required(),email:f.string().email().required(),username:f.string().min(4).required(),password:f.string().min(5).required()}),z(0,r()),z(1,n()),z(2,h()),z(3,h("username")),M("design:type",Function),M("design:paramtypes",[Object,Object,Object,String]),M("design:returntype",Promise)],Te.prototype,"register",null),Te=H([p("/register")],Te);let Se=class extends fe{model(){return V}create(){return{name:f.string().required(),description:f.string().empty(""),state:f.boolean().parse().required()}}update(){return{name:f.string().empty(),description:f.string().empty(),state:f.boolean().empty()}}};Se=H([p("/routes")],Se);let Re=class extends ve{setup(e){return X(this,void 0,void 0,(function*(){if(0==(yield te.count())){const e={description:"",state:!0},t=yield te.create(Object.assign({name:"Admin",email:"admin@localhost",username:"admin",password:"8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",avatar:""},e)),r=yield Q.create(Object.assign({name:"admin"},e));yield re.create({userId:t.id,groupId:r.id});const n=["read","write"],i=["users","groups","routes"];yield R(i,(t=>X(this,void 0,void 0,(function*(){yield R(n,(n=>X(this,void 0,void 0,(function*(){const i=t+"."+n,s=yield V.create(Object.assign({name:i},e));yield ee.create({groupId:r.id,routeId:s.id})}))))}))));const s=yield V.create(Object.assign({name:"logs.read"},e));yield ee.create({groupId:r.id,routeId:s.id})}return d.success(e,"OK")}))}};H([l(),z(0,r()),M("design:type",Function),M("design:paramtypes",[Object]),M("design:returntype",Promise)],Re.prototype,"setup",null),Re=H([p("/setup")],Re);let we=class extends Ie{constructor(){super(...arguments),this.attributes=["id","name","email","username","avatar","description","state","created","updated"]}model(){return te}userAdd(e,t){return X(this,void 0,void 0,(function*(){return t.body.password=C(t.body.password).toString(),yield this.add(t,e)}))}userAll(e,t){return X(this,void 0,void 0,(function*(){return this.all(t,e,{attributes:this.attributes})}))}userDel(e,t,r,n){return X(this,void 0,void 0,(function*(){return r&&r.id.toString()!=n?this.del(t,e):d.error(e,"Internal Server Error")}))}userGet(e,t){return X(this,void 0,void 0,(function*(){return this.get(t,e,{attributes:this.attributes})}))}userSet(e,t){return X(this,void 0,void 0,(function*(){return t.body.password&&(t.body.password=C(t.body.password).toString()),this.set(t,e)}))}};H([a(),u("auth"),u("write"),u("validation",{name:f.string().required(),email:f.string().email().required(),username:f.string().min(4).required(),password:f.string().min(5).required(),description:f.string().required(),state:f.boolean().parse().required()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],we.prototype,"userAdd",null),H([l(),u("auth"),u("read"),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],we.prototype,"userAll",null),H([m("/:id"),u("auth"),u("write"),z(0,r()),z(1,n()),z(2,ye()),z(3,y("id")),M("design:type",Function),M("design:paramtypes",[Object,Object,te,String]),M("design:returntype",Promise)],we.prototype,"userDel",null),H([l("/:id"),u("auth"),u("read"),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],we.prototype,"userGet",null),H([g("/:id"),u("auth"),u("write"),u("validation",{name:f.string().empty(),email:f.string().email().empty(),username:f.string().min(4).empty(),password:f.string().min(5).empty(),description:f.string().empty(),state:f.boolean().parse().empty()}),z(0,r()),z(1,n()),M("design:type",Function),M("design:paramtypes",[Object,Object]),M("design:returntype",Promise)],we.prototype,"userSet",null),we=H([p("/users")],we);let je=class extends Ie{model(){return re}userGroupsAll(e,t,r){return X(this,void 0,void 0,(function*(){return this.all(t,e,{where:{userId:r},include:[{model:Q,required:!0}]},(e=>e.map((e=>e.group))))}))}userGroupsSet(e,t,r){return X(this,void 0,void 0,(function*(){const n=yield te.findByPk(t,{attributes:["id"]}).catch(this.error);if(n){if(yield re.destroy({where:{userId:n.id}}),r){let e=0;for(let t=0;t<r.length;t++)e=yield Q.count({where:{id:r[t]}}),e&&(yield re.create({userId:n.id,groupId:r[t]}))}return d.success(e,"OK")}return S(n)?d.notfound(e,"Record not found"):d.error(e,"Internal Server Error")}))}};H([l("/:id/groups"),u("auth"),u("read","groups"),z(0,r()),z(1,n()),z(2,y("id")),M("design:type",Function),M("design:paramtypes",[Object,Object,String]),M("design:returntype",Promise)],je.prototype,"userGroupsAll",null),H([g("/:id/groups"),u("auth"),u("write","groups"),u("validation",{groups:f.array(f.number().parse())}),z(0,r()),z(1,y("id")),z(2,h("groups")),M("design:type",Function),M("design:paramtypes",[Object,String,Array]),M("design:returntype",Promise)],je.prototype,"userGroupsSet",null),je=H([p("/users")],je);export{le as Application,Z as Auth,Oe as AuthController,pe as Config,ne as Configs,ve as ControllerBase,fe as CrudController,W as Database,Y as Env,$ as Forgot,_e as ForgotController,Q as Group,Ae as GroupController,ee as GroupRoute,Pe as GroupRouteController,oe as Log,ie as Logs,Ee as LogsController,Ie as ModelController,me as Permission,Te as RegisterController,ge as ReqAuth,ye as ReqUser,V as Route,Se as RouteController,Re as SetupController,ce as Token,te as User,we as UserController,re as UserGroup,je as UserGroupController,ae as crt,ue as key,J as sequelize};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andrewcaires/api",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "Simple api for small applications using express, jsonwebtoken, sequelize and websocket",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "types": "./dist/index.d.ts",
@@ -56,7 +56,7 @@
56
56
  "mime-types": "^2.1.35",
57
57
  "multer": "^1.4.5-lts.1",
58
58
  "mysql2": "^3.2.0",
59
- "sequelize": "^6.29.1",
59
+ "sequelize": "^6.29.2",
60
60
  "ws": "^8.12.1"
61
61
  },
62
62
  "devDependencies": {