@andrewcaires/api 2.0.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -7
- package/dist/index.cjs.js +3 -3
- package/dist/index.d.ts +146 -126
- package/dist/index.esm.js +3 -3
- package/package.json +22 -21
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ The module is now available on npm! `npm i @andrewcaires/api`
|
|
|
19
19
|
NODE_ENV=development
|
|
20
20
|
|
|
21
21
|
API_DB_TYPE=mariadb
|
|
22
|
-
API_DB_DATABASE=
|
|
22
|
+
API_DB_DATABASE=database
|
|
23
23
|
API_DB_HOST=localhost
|
|
24
24
|
API_DB_USERNAME=root
|
|
25
25
|
API_DB_PASSWORD=
|
|
@@ -30,11 +30,11 @@ API_HTTP_PORT=3000
|
|
|
30
30
|
API_HTTP_PUBLIC=/public
|
|
31
31
|
API_HTTP_CROSS=true
|
|
32
32
|
|
|
33
|
-
API_HTTP_CRT
|
|
34
|
-
API_HTTP_KEY
|
|
33
|
+
API_HTTP_CRT=http.crt
|
|
34
|
+
API_HTTP_KEY=http.key
|
|
35
35
|
|
|
36
|
-
API_TOKEN_CRT
|
|
37
|
-
API_TOKEN_KEY
|
|
36
|
+
API_TOKEN_CRT=token.crt
|
|
37
|
+
API_TOKEN_KEY=token.key
|
|
38
38
|
API_TOKEN_LIFETIME=3000
|
|
39
39
|
|
|
40
40
|
API_WEBSOCKET_START=false
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
|
|
58
58
|
} from "@andrewcaires/api";
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
const main = async () => {
|
|
61
61
|
|
|
62
62
|
const app = new App(
|
|
63
63
|
[
|
|
@@ -75,7 +75,9 @@ import {
|
|
|
75
75
|
|
|
76
76
|
await app.listen();
|
|
77
77
|
|
|
78
|
-
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
main().catch(console.log);
|
|
79
81
|
```
|
|
80
82
|
|
|
81
83
|
### Links
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/api
|
|
2
|
+
* @andrewcaires/api v3.0.0
|
|
3
3
|
* Simple api for small applications using express, jsonwebtoken, sequelize and websocket
|
|
4
|
-
* (c)
|
|
4
|
+
* (c) 2023 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
6
6
|
*/
|
|
7
|
-
"use strict";var e=require("@andrewcaires/utils.js"),t=require("cors"),r=require("express"),s=require("fs"),i=require("http"),o=require("https"),n=require("net"),a=require("ws"),d=require("dotenv"),u=require("sequelize"),l=require("jsonwebtoken"),c=require("mime-types"),h=require("multer"),p=require("path"),m=require("crypto-js");function v(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var g=v(i),f=v(o);function y(e,t,r,s){return new(r||(r=Promise))((function(i,o){function n(e){try{d(s.next(e))}catch(e){o(e)}}function a(e){try{d(s.throw(e))}catch(e){o(e)}}function d(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,a)}d((s=s.apply(e,t||[])).next())}))}d.config();const _=parseInt(process.env.API_AUTH_SLEEP||"1000"),I=process.env.API_DB_DATABASE||"",T=process.env.API_DB_HOST||"127.0.0.1",A=process.env.API_DB_PASSWORD||"",w=parseInt(process.env.API_DB_PORT||"3306"),S=process.env.API_DB_TYPE||"",b=process.env.API_DB_USERNAME||"root",P=e.toBool(process.env.API_DB_LOG||"false"),x=process.env.API_HTTP_CRT||"",E=process.env.API_HTTP_KEY||"",O=parseInt(process.env.API_HTTP_PORT||"3000"),q=process.env.API_HTTP_PUBLIC||"",D=e.toBool(process.env.API_HTTP_CROSS||"false"),R=e.toBool(process.env.API_HTTP_HYBRID||"false"),N=process.env.API_TOKEN_CRT||"",k=process.env.API_TOKEN_KEY||"",B=process.env.API_TOKEN_HEADER||"authorization",C=parseInt(process.env.API_TOKEN_LIFETIME||"15"),z=parseInt(process.env.API_UPLOAD_COUNT||"1"),j=process.env.API_UPLOAD_FIELD||"upload",G=parseInt(process.env.API_UPLOAD_SIZE||"2"),V=process.env.API_UPLOAD_TEMP||"./temp",M=e.toBool(process.env.API_WEBSOCKET_START||"false");class L{static connect(e){const t=S.toLowerCase();if("connect_"+t in L)return L["connect_"+t](e);throw new Error("No database is connected to this API")}static connect_mariadb(e){return new u.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mariadb",logging:P,define:{timestamps:!1}})}static connect_memory(){return new u.Sequelize("sqlite::memory:",{logging:P,define:{timestamps:!1}})}static connect_mysql(e){return new u.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mysql",logging:P,define:{timestamps:!1}})}static connect_postgres(e){return new u.Sequelize(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"postgres",logging:P,define:{timestamps:!1}})}static connect_sqlite(e){return new u.Sequelize({dialect:"sqlite",storage:e.database,logging:P,define:{timestamps:!1}})}}const U=L.connect({database:I,username:b,password:A,hostname:T,hostport:w});class H extends u.Model{}H.init({login:u.DataTypes.BIGINT,logout:u.DataTypes.BIGINT,secret:u.DataTypes.STRING,timestamp:u.DataTypes.BIGINT,useragent:u.DataTypes.STRING},{sequelize:U,modelName:"auth"});class K extends u.Model{}K.init({name:u.DataTypes.STRING,description:u.DataTypes.TEXT,state:u.DataTypes.BOOLEAN},{sequelize:U,modelName:"group"});class F extends u.Model{}F.init({name:u.DataTypes.STRING,description:u.DataTypes.TEXT,state:u.DataTypes.BOOLEAN},{sequelize:U,modelName:"route"});class Y extends u.Model{}Y.init({},{sequelize:U,modelName:"groups_routes"}),Y.removeAttribute("id");class W extends u.Model{}W.init({name:u.DataTypes.STRING,email:u.DataTypes.STRING,username:u.DataTypes.STRING,password:u.DataTypes.STRING,description:u.DataTypes.TEXT,state:u.DataTypes.BOOLEAN},{sequelize:U,modelName:"user"});class X extends u.Model{}X.init({},{sequelize:U,modelName:"users_groups"}),X.removeAttribute("id");class J extends u.Model{}J.init({key:u.DataTypes.STRING,value:u.DataTypes.STRING},{sequelize:U,modelName:"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),J.removeAttribute("id");class Z extends u.Model{}var $;Z.init({type:u.DataTypes.STRING,source:u.DataTypes.STRING,message:u.DataTypes.TEXT},{sequelize:U,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),W.hasMany(H),H.belongsTo(W),K.hasMany(Y),Y.belongsTo(K),F.hasMany(Y),Y.belongsTo(F),W.hasMany(X),X.belongsTo(W),K.hasMany(X),X.belongsTo(K),function(e){e.ERROR="[31m",e.INFO="[36m",e.NONE="[37m",e.SUCCESS="[32m",e.WARNING="[33m"}($||($={}));class Q{static write(e,t,r){return y(this,void 0,void 0,(function*(){yield Q.writeRaw($.NONE,"",e,t,r)}))}static error(e,t,r){return y(this,void 0,void 0,(function*(){yield Q.writeRaw($.ERROR,"error",e,t,r)}))}static info(e,t,r){return y(this,void 0,void 0,(function*(){yield Q.writeRaw($.INFO,"info",e,t,r)}))}static success(e,t,r){return y(this,void 0,void 0,(function*(){yield Q.writeRaw($.ERROR,"success",e,t,r)}))}static warning(e,t,r){return y(this,void 0,void 0,(function*(){yield Q.writeRaw($.WARNING,"warning",e,t,r)}))}static writeConsole(t,r,s){const i=e.dateFormat(new Date,"%H:%M:%S");console.log(">",t,r+" ".repeat(10-r.length),"[37m","|",i,"|",s)}static writeRaw(e,t,r,s,i){return y(this,void 0,void 0,(function*(){i&&Q.writeConsole(e,t,r),U&&(yield Z.create({type:t,source:s,message:r}).catch((()=>null)))}))}}class ee{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t){return e.status(400).json({message:t})}static unauthorized(e,t){return e.status(401).json({message:t})}}const te=e=>s.existsSync(e)?s.readFileSync(e):void 0,re={http:te(x),token:te(N)},se={http:te(E),token:te(k)};class ie{static sign(e){return se.token?{token:l.sign(e,se.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static user(e){return y(this,void 0,void 0,(function*(){const{error:t,decode:r}=ie.verify(e);if(t)return{error:t};if(r){const{id:e,secret:t}=r;if(e&&r){const r=yield W.findOne({where:{id:e,state:!0}}).catch((e=>{Q.error(e.message,"api.token",!0)}));if(r){const e=yield H.findOne({where:{secret:t,userId:r.id}}).catch((e=>{Q.error(e.message,"api.token",!0)}));if(e){const t=Date.now();if(t>e.timestamp)return{error:"Expired token"};if(e.timestamp=t+6e4*C,yield e.save(),!e.logout)return{auth:e,user:r}}}return{error:"Access denied"}}}return{error:"Invalid token"}}))}static verify(e){if(!re.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:l.verify(e,re.token)}}catch(e){return{error:"Invalid Token"}}}}class oe extends e.EventEmitter{constructor(e){super(),this.app=r(),this.router=r.Router(),this.middlewares(),this.controllers(e)}controllers(e){e.forEach((e=>{e.intialize(),this.router.use(e.path(),e.router)}))}listen(){return y(this,void 0,void 0,(function*(){if(yield U.sync(),re.http&&se.http||(this._server=g.createServer(this.app),this._server.listen(O,(()=>Q.info("Server started on port "+O,"api.server",!0)))),!this._server){const e=g.createServer(((e,t)=>{const r=80==O?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),t=f.createServer({key:se.http,cert:re.http},this.app);if(R){new n.Server((r=>{r.once("data",(s=>{r.pause(),r.unshift(s),(22===s[0]?t:e).emit("connection",r),process.nextTick((()=>r.resume()))}))})).listen(O,(()=>Q.info("Server started on port "+O,"api.server",!0))),this._server=t}this._server||(443==O&&e.listen(80,(()=>Q.info("Server started on port 80","api.server",!0))),t.listen(O,(()=>Q.info("Server started on port "+O,"api.server",!0))),this._server=t)}M&&this._server&&(this._webSocket=new a.Server({server:this._server,verifyClient:(e,t)=>t(M)}),this._webSocket.on("connection",((t,r)=>y(this,void 0,void 0,(function*(){r.url||(r.url="");const s=r.url.length<=1?"":r.url.replace(/\//g,".");let i;t.on("message",(e=>y(this,void 0,void 0,(function*(){if(i)try{const o=JSON.parse(e);this.emit("ws.message"+s,{data:o,message:e,req:r,user:i,ws:t})}catch(o){this.emit("ws.message"+s,{message:e,req:r,user:i,ws:t})}else{const{user:o}=yield ie.user(e.toString());o&&(i=o,this.emit("ws.connection"+s,{req:r,user:i,ws:t}))}i||t.close()})))),t.on("close",(()=>{i&&this.emit("ws.close"+s,{user:i,ws:t})})),yield e.sleep(2e3),i||t.close()})))))}))}middlewares(){this.app.use(r.json()),this.app.use(((e,t,r,s)=>e?(Q.error(e.message,"api.express",!0),ee.error(r,"Internal Server Error")):s())),this.app.use(r.urlencoded({extended:!0})),this.app.disable("x-powered-by"),D&&this.app.use(t()),this.app.use("/api",this.router),this.app.all("/api/*",((e,t)=>ee.notfound(t,"Invalid API"))),q&&(s.existsSync(q)&&this.app.use(r.static(q)),this.app.get("*",((e,t)=>{if(!s.existsSync(q))return ee.notfound(t,'File "index.html" not found');t.sendFile(q+"/index.html")})))}server(){return this._server}websocket(){return this._webSocket}}class ne{static all(e,t){return y(this,void 0,void 0,(function*(){return yield F.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:Y,required:!0,include:[{model:K,required:!0,where:{state:!0},include:[{model:X,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{Q.error(e.message,"api.permission",!0)}))}))}static get(e){return y(this,void 0,void 0,(function*(){const t=yield ne.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return y(this,void 0,void 0,(function*(){const r=yield ne.all(e,{name:t});return r&&!!r.length}))}}const ae=(t,r)=>{const i=e.uuidv4()+"."+r;return s.existsSync(p.join(t,i))?ae(t,r):i};class de{constructor(e){this.router=r.Router(),this._path=e}auth(e,t,r){return y(this,void 0,void 0,(function*(){const s=e.get(B)||"",{auth:i,error:o,user:n}=yield ie.user(s);if(o)return ee.error(t,o);if(i&&n){const t=e.get("User-Agent");return t&&(i.useragent=t),yield i.save(),e.auth=i,e.user=n,r()}return ee.error(t,"Internal Server Error")}))}intialize(){}name(){return"api"}path(){return this._path}permission(e){return(t,r,s)=>y(this,void 0,void 0,(function*(){const i=t.user;return i?(yield ne.is(i,e))?s():ee.error(r,"Unauthorized access"):ee.unauthorized(r,"Access denied")}))}read(e=""){return this.permission((e||this.name())+".read")}upload(e){const t=(null==e?void 0:e.path)||V,r=h.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>y(this,void 0,void 0,(function*(){return s(null,ae(t,c.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||G),i=h({storage:r,fileFilter(t,r,s){var i;return y(this,void 0,void 0,(function*(){const t=null===(i=null==e?void 0:e.types)||void 0===i?void 0:i.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),o=(null==e?void 0:e.count)||z,n=(null==e?void 0:e.field)||j,a=i.array(n,o);return(e,t,r)=>{a(e,t,(function(e){return e?ee.error(t,e.message):r()}))}}validation(t){return(r,s,i)=>y(this,void 0,void 0,(function*(){const{error:o,value:n}=yield e.Validation.object(t).validateAsync(r.body);return o?ee.validation(s,o):(r.body=n,i())}))}write(e=""){return this.permission((e||this.name())+".write")}}class ue extends de{add(){return(e,t)=>y(this,void 0,void 0,(function*(){if(!this._model)return ee.error(t,"Internal Server Error");const r=yield this._model.create(e.body).catch((e=>{Q.error(e.message,"api.controller."+this.name(),!0)}));return r?ee.data(t,{id:r.id}):ee.error(t,"Internal Server Error")}))}all(t,r){return(s,i)=>y(this,void 0,void 0,(function*(){var o,n,a,d,l;if(!this._model)return ee.error(i,"Internal Server Error");const c=Object.assign({},t||{});c.where=Object.assign({},c.where||{});const h=null===(o=s.query.limit)||void 0===o?void 0:o.toString();h&&(c.limit=parseInt(h));const p=null===(n=s.query.offset)||void 0===n?void 0:n.toString();p&&(c.offset=parseInt(p));const m=Object.keys(this._model.getAttributes()),v=[],g=null===(a=s.query.asc)||void 0===a?void 0:a.toString();g&&g.length&&g.split(",").forEach((e=>{m.indexOf(e)>=0&&v.push([e,"ASC"])}));const f=null===(d=s.query.desc)||void 0===d?void 0:d.toString();f&&f.length&&f.split(",").forEach((e=>{m.indexOf(e)>=0&&v.push([e,"DESC"])})),v.length&&(c.order=v);const y=[],_=e.isArray(c.attributes)?c.attributes:m,I=null===(l=s.query.search)||void 0===l?void 0:l.toString();_.forEach((t=>{var r;if(e.isString(t)&&(I&&I.length&&y.push({[t]:{[u.Op.like]:`%${I}%`}}),"search_"+t in s.query)){const e=null===(r=s.query["search_"+t])||void 0===r?void 0:r.toString();e&&e.length&&y.push({[t]:{[u.Op.like]:`%${e}%`}})}})),y.length&&(c.where=Object.assign(Object.assign({},c.where),{[u.Op.or]:[...y]}));const T=yield this._model.findAll(c).catch((e=>{Q.error(e.message,"api.controller."+this.name(),!0)})),A=yield this._model.count(c).catch(e.noop);return T?ee.data(i,{count:A,records:r?r(T):T}):ee.error(i,"Internal Server Error")}))}del(){return(e,t)=>y(this,void 0,void 0,(function*(){if(!this._model)return ee.error(t,"Internal Server Error");const{id:r}=e.params;return(yield this._model.destroy({where:{id:r}}).catch((e=>{Q.error(e.message,"api.controller."+this.name(),!0)})))?ee.success(t,"OK"):ee.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>y(this,void 0,void 0,(function*(){if(!this._model)return ee.error(s,"Internal Server Error");e||(e={});const i=Object.assign({},e);i.where=i.where?Object.assign({},i.where):{};const{id:o}=r.params,n=yield this._model.findByPk(o,i).catch((e=>{Q.error(e.message,"api.controller."+this.name(),!0)}));return n?ee.data(s,t?t(n):n.toJSON()):null===n?ee.notfound(s,"Record not found"):ee.error(s,"Internal Server Error")}))}name(){var e;return this._model?null===(e=this._model)||void 0===e?void 0:e.tableName:super.name()}set(){return(e,t)=>y(this,void 0,void 0,(function*(){if(!this._model)return ee.error(t,"Internal Server Error");const{id:r}=e.params,[s]=(yield this._model.update(e.body,{where:{id:r}}).catch((e=>{Q.error(e.message,"api.controller."+this.name(),!0)})))||[];return s?ee.success(t,"OK"):ee.success(t,"Record not changed")}))}getModel(){return this._model}setModel(e){this._model=e}}class le extends ue{intialize(){const e=this.model();e&&this.setModel(e),this.router.use(this.auth),this.router.get("/",this.read(),this.all().bind(this)),this.router.post("/",this.write(),this.validation(this.create()),this.add().bind(this)),this.router.route("/:id").get(this.read(),this.get().bind(this)).put(this.write(),this.validation(this.update()),this.set().bind(this)).delete(this.write(),this.del().bind(this))}}exports.API_AUTH_SLEEP=_,exports.API_DB_DATABASE=I,exports.API_DB_HOST=T,exports.API_DB_LOG=P,exports.API_DB_PASSWORD=A,exports.API_DB_PORT=w,exports.API_DB_TYPE=S,exports.API_DB_USERNAME=b,exports.API_HTTP_CROSS=D,exports.API_HTTP_CRT=x,exports.API_HTTP_HYBRID=R,exports.API_HTTP_KEY=E,exports.API_HTTP_PORT=O,exports.API_HTTP_PUBLIC=q,exports.API_TOKEN_CRT=N,exports.API_TOKEN_HEADER=B,exports.API_TOKEN_KEY=k,exports.API_TOKEN_LIFETIME=C,exports.API_UPLOAD_COUNT=z,exports.API_UPLOAD_FIELD=j,exports.API_UPLOAD_SIZE=G,exports.API_UPLOAD_TEMP=V,exports.API_WEBSOCKET_START=M,exports.App=oe,exports.Auth=H,exports.AuthController=class extends de{constructor(){super(...arguments),this.attributes=["id","name","email","username"],this.query={username:e.Validation.string().min(4).required(),password:e.Validation.string().min(5).required()}}intialize(){this.router.get("/",this.auth,this.user.bind(this)),this.router.post("/login",this.validation(this.query),this.login.bind(this)),this.router.get("/logout",this.auth,this.logout.bind(this))}login(t,r){return y(this,void 0,void 0,(function*(){yield e.sleep(_);const{username:s,password:i}=t.body,o=yield W.findOne({where:{username:s}}).catch((e=>{Q.error(e.message,"api.controller."+this.name(),!0)}));if(!o)return ee.notfound(r,"Username not found");if(!o.state)return ee.error(r,"Username is disabled");const n=m.SHA256(i).toString();if(o.password!=n)return ee.error(r,"Invalid password");const a=o.id,d=e.uniqueID(),{error:u,token:l}=ie.sign({id:a,secret:d});if(u)return ee.error(r,u);if(l){const e=Date.now(),s=e+6e4*C,i=t.get("User-Agent"),o=yield H.create({login:e,secret:d,timestamp:s,useragent:i,userId:a}).catch((e=>{Q.error(e.message,"api.controller."+this.name(),!0)}));if(o)return ee.data(r,{token:l})}return ee.error(r,"Internal Server Error")}))}logout(e,t){return y(this,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),ee.success(t,"Disconcerted")):ee.unauthorized(t,"Access denied")}))}user(t,r){return y(this,void 0,void 0,(function*(){const s=t.user;if(!s)return ee.unauthorized(r,"Access denied");const i=yield ne.all(s);if(i){const t=e.allowedObject(this.attributes,s.toJSON()),o=i.map((e=>e.name));return ee.data(r,Object.assign(Object.assign({},t),{permissions:o}))}return ee.error(r,"Internal Server Error")}))}},exports.Config=class{static all(){return y(this,void 0,void 0,(function*(){const e=yield J.findAll().catch((e=>{Q.error(e.message,"api.config",!0)})),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 J.destroy({where:{key:e}}).catch((e=>{Q.error(e.message,"api.config",!0)})))||0)>0}))}static get(e){return y(this,void 0,void 0,(function*(){const t=yield J.findOne({where:{key:e}}).catch((e=>{Q.error(e.message,"api.config",!0)}));return t&&t.value||""}))}static set(e,t){return y(this,void 0,void 0,(function*(){const[r]=(yield J.findOrCreate({where:{key:e}}).catch((e=>{Q.error(e.message,"api.config",!0)})))||[];r&&(r.value=t,yield r.save().catch((e=>{Q.error(e.message,"api.config",!0)})))}))}},exports.Configs=J,exports.Controller=de,exports.CrudController=le,exports.Database=L,exports.Group=K,exports.GroupController=class extends le{create(){return{name:e.Validation.string().required(),description:e.Validation.string().empty(""),state:e.Validation.boolean().required()}}model(){return K}update(){return{name:e.Validation.string().empty(),description:e.Validation.string().empty(),state:e.Validation.boolean().empty()}}},exports.GroupRoute=Y,exports.GroupRouteController=class extends ue{constructor(){super(...arguments),this.groups={groups:e.Validation.array().items(e.Validation.number())}}intialize(){this.setModel(Y),this.router.use(this.auth),this.router.route("/:id/groups").get(this.read("users"),this.groupRouteAll.bind(this)).put(this.write("users"),this.validation(this.groups),this.groupRouteSet.bind(this))}groupRouteAll(e,t){return y(this,void 0,void 0,(function*(){const{id:r}=e.params;return this.all({where:{groupId:r},include:[{model:F,required:!0}]},(e=>e.map((e=>e.route))))(e,t)}))}groupRouteSet(e,t){return y(this,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,i=yield K.findByPk(r,{attributes:["id"]}).catch((e=>{Q.error(e.message,"api.controller."+this.name(),!0)}));if(i){const e=i.id;if(yield Y.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield F.count({where:{id:s[r]}}),t&&(yield Y.create({groupId:e,routeId:s[r]}))}return ee.success(t,"OK")}return null===i?ee.notfound(t,"Record not found"):ee.error(t,"Internal Server Error")}))}},exports.Log=Q,exports.Logs=Z,exports.LogsController=class extends ue{intialize(){this.setModel(Z),this.router.use(this.auth),this.router.get("/",this.read("logs"),this.logsAll.bind(this))}logsAll(e,t){return y(this,void 0,void 0,(function*(){const{source:r,type:s}=e.query,i=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return this.all({where:i,order:[["created","DESC"]]})(e,t)}))}},exports.ModelController=ue,exports.Permission=ne,exports.Responses=ee,exports.Route=F,exports.RouteController=class extends le{create(){return{name:e.Validation.string().required(),description:e.Validation.string().empty(""),state:e.Validation.boolean().required()}}model(){return F}update(){return{name:e.Validation.string().empty(),description:e.Validation.string().empty(),state:e.Validation.boolean().empty()}}},exports.Token=ie,exports.User=W,exports.UserController=class extends ue{constructor(){super(...arguments),this.attributes=["id","name","email","username","description","state"],this.create={name:e.Validation.string().required(),email:e.Validation.string().email().required(),username:e.Validation.string().min(4).required(),password:e.Validation.string().min(5).required(),description:e.Validation.string().required(),state:e.Validation.boolean().required()},this.update={name:e.Validation.string().empty(),email:e.Validation.string().email().empty(),username:e.Validation.string().min(4).empty(),password:e.Validation.string().min(5).empty(),description:e.Validation.string().empty(),state:e.Validation.boolean().empty()}}intialize(){this.setModel(W),this.router.use(this.auth),this.router.get("/",this.read(),this.userAll.bind(this)),this.router.post("/",this.write(),this.validation(this.create),this.userAdd.bind(this)),this.router.route("/:id").get(this.read(),this.userGet.bind(this)).put(this.write(),this.validation(this.update),this.userSet.bind(this)).delete(this.write(),this.userDel.bind(this))}userAdd(e,t){return y(this,void 0,void 0,(function*(){return e.body.password=m.SHA256(e.body.password).toString(),yield this.add()(e,t)}))}userAll(e,t){return y(this,void 0,void 0,(function*(){return this.all({attributes:this.attributes})(e,t)}))}userDel(e,t){return y(this,void 0,void 0,(function*(){const r=e.user;if(r){const{id:s}=e.params;if(r.id.toString()!=s)return this.del()(e,t)}return ee.error(t,"Internal Server Error")}))}userGet(e,t){return y(this,void 0,void 0,(function*(){return this.get({attributes:this.attributes})(e,t)}))}userSet(e,t){return y(this,void 0,void 0,(function*(){return e.body.password&&(e.body.password=m.SHA256(e.body.password).toString()),this.set()(e,t)}))}},exports.UserGroup=X,exports.UserGroupController=class extends ue{constructor(){super(...arguments),this.groups={groups:e.Validation.array(e.Validation.number())}}intialize(){this.setModel(X),this.router.use(this.auth),this.router.route("/:id/groups").get(this.read("groups"),this.userGroupsAll.bind(this)).put(this.write("groups"),this.validation(this.groups),this.userGroupsSet.bind(this))}userGroupsAll(e,t){return y(this,void 0,void 0,(function*(){const{id:r}=e.params;return this.all({where:{userId:r},include:[{model:K,required:!0}]},(e=>e.map((e=>e.group))))(e,t)}))}userGroupsSet(e,t){return y(this,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,i=yield W.findByPk(r,{attributes:["id"]}).catch((e=>{Q.error(e.message,"api.controller."+this.name(),!0)}));if(i){if(yield X.destroy({where:{userId:i.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield K.count({where:{id:s[t]}}),e&&(yield X.create({userId:i.id,groupId:s[t]}))}return ee.success(t,"OK")}return ee.notfound(t,"Record not found")}))}},exports.crt=re,exports.key=se,exports.sequelize=U;
|
|
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 p(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 c(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=m.API_DB_TYPE.toLowerCase();if("connect_"+t in h)return h["connect_"+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="[31m",e.INFO="[36m",e.NONE="[37m",e.SUCCESS="[32m",e.WARNING="[33m"}(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),"[37m","|",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)),G=e.parameterFactory((({req:e})=>e.user)),B=(e,r)=>{const s=t.uuidv4()+"."+r;return n.existsSync(l.join(e,s))?B(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,B(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}}),p=(null==o?void 0:o.count)||m.API_UPLOAD_COUNT,c=(null==o?void 0:o.field)||m.API_UPLOAD_FIELD;l.array(c,p)(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")}}p([c(0,e.Res()),c(1,e.Req()),c(2,e.Headers(m.API_TOKEN_HEADER)),c(3,e.Headers("user-agent")),c(4,e.Next()),g("design:type",Function),g("design:paramtypes",[Object,Object,String,String,Function]),g("design:returntype",Promise)],M.prototype,"auth",null),p([c(0,e.Res()),c(1,G()),c(2,e.Next()),c(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,P,Function,String]),g("design:returntype",Promise)],M.prototype,"permission",null),p([c(0,e.Res()),c(1,G()),c(2,e.Next()),c(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,P,Function,String]),g("design:returntype",void 0)],M.prototype,"read",null),p([c(0,e.Res()),c(1,e.Req()),c(2,e.Next()),c(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function,Object]),g("design:returntype",void 0)],M.prototype,"upload",null),p([c(0,e.Res()),c(1,e.Req()),c(2,e.Next()),c(3,e.Argument()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function,Object]),g("design:returntype",Promise)],M.prototype,"validation",null),p([c(0,e.Res()),c(1,G()),c(2,e.Next()),c(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 p=u.id,c=t.uniqueID(),{error:g,token:y}=C.sign({id:p,secret:c});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:c,timestamp:n,useragent:o,userId:p}).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")}))}},p([e.Post("/login"),e.Middleware("validation",{username:t.Validation.string().min(4).required(),password:t.Validation.string().min(5).required()}),c(0,e.Res()),c(1,e.Req()),c(2,e.Headers("user-agent")),c(3,e.App()),g("design:type",Function),g("design:paramtypes",[Object,Object,String,D]),g("design:returntype",Promise)],exports.AuthController.prototype,"login",null),p([e.Get("/logout"),e.Middleware("auth"),c(0,e.Res()),c(1,e.Req()),c(2,F()),c(3,G()),c(4,e.App()),g("design:type",Function),g("design:paramtypes",[Object,Object,v,P,D]),g("design:returntype",Promise)],exports.AuthController.prototype,"logout",null),p([e.Get(),e.Middleware("auth"),c(0,e.Res()),c(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.AuthController.prototype,"user",null),exports.AuthController=p([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)}))}},p([e.Get("/check"),e.Middleware("validation",{token:t.Validation.string().required()}),c(0,e.Res()),c(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.ForgotController.prototype,"check",null),p([e.Get(),e.Middleware("validation",{username:t.Validation.string().min(4).required()}),c(0,e.Res()),c(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.ForgotController.prototype,"forgot",null),p([e.Get("/reset"),e.Middleware("validation",{token:t.Validation.string().required(),password:t.Validation.string().min(5).required()}),c(0,e.Res()),c(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.ForgotController.prototype,"reset",null),exports.ForgotController=p([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,p;return y(this,void 0,void 0,(function*(){const c=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(c.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===(p=r.query.search)||void 0===p?void 0:p.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 c.count(Object.assign(Object.assign({},g),{col:h[0]})).catch(this.error),f=yield c.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){super.error(e),e.sql&&b.error(e.sql,"api.controller.sql",m.API_CONSOLE_ERROR)}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{}}crudAdd(e,t){return this.add(e,t,this.optionsAdd())}crudAll(e,t){return this.all(e,t,this.optionsAll())}crudDel(e,t){return this.del(e,t,this.optionsDel())}crudGet(e,t){return this.get(e,t,this.optionsGet())}crudSet(e,t){return this.set(e,t,this.optionsSet())}optionsAdd(){return{}}optionsAll(){return{}}optionsDel(){return{}}optionsGet(){return{}}optionsSet(){return{where:{}}}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())}}p([e.Post(),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validationAdd"),c(0,e.Req()),c(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"crudAdd",null),p([e.Get(),e.Middleware("auth"),e.Middleware("read"),c(0,e.Req()),c(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"crudAll",null),p([e.Delete("/:id"),e.Middleware("auth"),e.Middleware("write"),c(0,e.Req()),c(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"crudDel",null),p([e.Get("/:id"),e.Middleware("auth"),e.Middleware("read"),c(0,e.Req()),c(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"crudGet",null),p([e.Put("/:id"),e.Middleware("auth"),e.Middleware("write"),e.Middleware("validationSet"),c(0,e.Req()),c(1,e.Res()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",void 0)],k.prototype,"crudSet",null),p([c(0,e.Req()),c(1,e.Res()),c(2,e.Next()),g("design:type",Function),g("design:paramtypes",[Object,Object,Function]),g("design:returntype",void 0)],k.prototype,"validationAdd",null),p([c(0,e.Req()),c(1,e.Res()),c(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=p([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")}))}},p([e.Get("/:id/routes"),e.Middleware("auth"),e.Middleware("read","routes"),c(0,e.Res()),c(1,e.Req()),c(2,e.Params("id")),g("design:type",Function),g("design:paramtypes",[Object,Object,String]),g("design:returntype",Promise)],exports.GroupRouteController.prototype,"groupRouteAll",null),p([e.Put("/:id/groups"),e.Middleware("auth"),e.Middleware("write","groups"),e.Middleware("validation",{routes:t.Validation.array(t.Validation.number().parse())}),c(0,e.Res()),c(1,e.Params("id")),c(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=p([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"]]})}))}},p([e.Get(),e.Middleware("auth"),e.Middleware("read"),c(0,e.Res()),c(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.LogsController.prototype,"logsAll",null),exports.LogsController=p([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")}))}},p([e.Get("/confirm"),e.Middleware("validation",{token:t.Validation.string().required()}),c(0,e.Res()),c(1,e.Body("token")),g("design:type",Function),g("design:paramtypes",[Object,String]),g("design:returntype",Promise)],exports.RegisterController.prototype,"confirm",null),p([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()}),c(0,e.Res()),c(1,e.Req()),c(2,e.Body()),c(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=p([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=p([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")}))}},p([e.Get(),c(0,e.Res()),g("design:type",Function),g("design:paramtypes",[Object]),g("design:returntype",Promise)],exports.SetupController.prototype,"setup",null),exports.SetupController=p([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)}))}},p([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()}),c(0,e.Res()),c(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userAdd",null),p([e.Get(),e.Middleware("auth"),e.Middleware("read"),c(0,e.Res()),c(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userAll",null),p([e.Delete("/:id"),e.Middleware("auth"),e.Middleware("write"),c(0,e.Res()),c(1,e.Req()),c(2,G()),c(3,e.Params("id")),g("design:type",Function),g("design:paramtypes",[Object,Object,P,String]),g("design:returntype",Promise)],exports.UserController.prototype,"userDel",null),p([e.Get("/:id"),e.Middleware("auth"),e.Middleware("read"),c(0,e.Res()),c(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userGet",null),p([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()}),c(0,e.Res()),c(1,e.Req()),g("design:type",Function),g("design:paramtypes",[Object,Object]),g("design:returntype",Promise)],exports.UserController.prototype,"userSet",null),exports.UserController=p([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")}))}},p([e.Get("/:id/groups"),e.Middleware("auth"),e.Middleware("read","groups"),c(0,e.Res()),c(1,e.Req()),c(2,e.Params("id")),g("design:type",Function),g("design:paramtypes",[Object,Object,String]),g("design:returntype",Promise)],exports.UserGroupController.prototype,"userGroupsAll",null),p([e.Put("/:id/groups"),e.Middleware("auth"),e.Middleware("write","groups"),e.Middleware("validation",{groups:t.Validation.array(t.Validation.number().parse())}),c(0,e.Res()),c(1,e.Params("id")),c(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=p([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=G,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,18 +1,15 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/api
|
|
2
|
+
* @andrewcaires/api v3.0.0
|
|
3
3
|
* Simple api for small applications using express, jsonwebtoken, sequelize and websocket
|
|
4
|
-
* (c)
|
|
4
|
+
* (c) 2023 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
6
6
|
*/
|
|
7
|
-
import * as
|
|
8
|
-
import {
|
|
9
|
-
import * as http from 'http';
|
|
10
|
-
import * as https from 'https';
|
|
7
|
+
import * as _andrewcaires_express from '@andrewcaires/express';
|
|
8
|
+
import { Application as Application$1 } from '@andrewcaires/express';
|
|
11
9
|
import WebSocket from 'ws';
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import { Model,
|
|
15
|
-
import { WhereOptions } from 'sequelize/types';
|
|
10
|
+
import { EventEmitter, TypeObject, ValidationBase, TypeObjectString } from '@andrewcaires/utils.js';
|
|
11
|
+
import { Response, Request, NextFunction } from 'express';
|
|
12
|
+
import { Model, CreateOptions, Attributes, FindOptions, ModelStatic, UpdateOptions, Sequelize, WhereOptions } from 'sequelize';
|
|
16
13
|
|
|
17
14
|
declare class Route extends Model {
|
|
18
15
|
id: number;
|
|
@@ -24,8 +21,8 @@ declare class Route extends Model {
|
|
|
24
21
|
|
|
25
22
|
declare class GroupRoute extends Model {
|
|
26
23
|
groupId: number;
|
|
27
|
-
routeId: number;
|
|
28
24
|
group: Group;
|
|
25
|
+
routeId: number;
|
|
29
26
|
route: Route;
|
|
30
27
|
}
|
|
31
28
|
|
|
@@ -40,8 +37,8 @@ declare class Group extends Model {
|
|
|
40
37
|
|
|
41
38
|
declare class UserGroup extends Model {
|
|
42
39
|
userId: number;
|
|
43
|
-
groupId: number;
|
|
44
40
|
user: User;
|
|
41
|
+
groupId: number;
|
|
45
42
|
group: Group;
|
|
46
43
|
}
|
|
47
44
|
|
|
@@ -51,6 +48,7 @@ declare class User extends Model {
|
|
|
51
48
|
email: string;
|
|
52
49
|
username: string;
|
|
53
50
|
password: string;
|
|
51
|
+
avatar: string;
|
|
54
52
|
description: string;
|
|
55
53
|
state: boolean;
|
|
56
54
|
users_groups: UserGroup[];
|
|
@@ -63,6 +61,16 @@ declare class Auth extends Model {
|
|
|
63
61
|
secret: string;
|
|
64
62
|
timestamp: number;
|
|
65
63
|
useragent: string;
|
|
64
|
+
userId: number;
|
|
65
|
+
user: User;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
declare class Forgot extends Model {
|
|
69
|
+
id: number;
|
|
70
|
+
token: string;
|
|
71
|
+
timestamp: number;
|
|
72
|
+
state: boolean;
|
|
73
|
+
userId: number;
|
|
66
74
|
user: User;
|
|
67
75
|
}
|
|
68
76
|
|
|
@@ -77,14 +85,6 @@ declare class Logs extends Model {
|
|
|
77
85
|
message: string;
|
|
78
86
|
}
|
|
79
87
|
|
|
80
|
-
declare global {
|
|
81
|
-
namespace Express {
|
|
82
|
-
interface Request {
|
|
83
|
-
auth?: Auth;
|
|
84
|
-
user?: User;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
88
|
interface UploadOptions {
|
|
89
89
|
count?: number;
|
|
90
90
|
field?: string;
|
|
@@ -92,136 +92,124 @@ interface UploadOptions {
|
|
|
92
92
|
size?: number;
|
|
93
93
|
types?: string[];
|
|
94
94
|
}
|
|
95
|
-
declare abstract class
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
constructor(path: string);
|
|
99
|
-
protected auth(req: Request, res: Response, next: NextFunction): Promise<void | Response<any, Record<string, any>>>;
|
|
100
|
-
intialize(): void;
|
|
95
|
+
declare abstract class ControllerBase extends EventEmitter {
|
|
96
|
+
auth(res: Response, req: Request, token: string, useragent: string, next: NextFunction): Promise<void | _andrewcaires_express.ResponseJson>;
|
|
97
|
+
error(error: any): void;
|
|
101
98
|
protected name(): string;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
protected write(name?: string): (req: Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
|
|
99
|
+
permission(res: Response, user: User, next: NextFunction, name: string): Promise<void | _andrewcaires_express.ResponseJson>;
|
|
100
|
+
read(res: Response, user: User, next: NextFunction, name: string): Promise<void | _andrewcaires_express.ResponseJson>;
|
|
101
|
+
upload(res: Response, req: Request, next: NextFunction, options: UploadOptions): void;
|
|
102
|
+
validation(res: Response, req: Request, next: NextFunction, options: TypeObject<ValidationBase>): Promise<void | _andrewcaires_express.ResponseJson>;
|
|
103
|
+
write(res: Response, user: User, next: NextFunction, name: string): Promise<void | _andrewcaires_express.ResponseJson>;
|
|
108
104
|
}
|
|
109
105
|
|
|
110
|
-
declare class
|
|
111
|
-
private _server?;
|
|
106
|
+
declare class Application extends Application$1 {
|
|
112
107
|
private _webSocket?;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
private controllers;
|
|
108
|
+
constructor(controllers: Array<ControllerBase>);
|
|
109
|
+
error(error: any, source?: string): void;
|
|
110
|
+
log(message: string, source?: string): void;
|
|
117
111
|
listen(): Promise<void>;
|
|
118
|
-
private middlewares;
|
|
119
|
-
server(): http.Server | https.Server | undefined;
|
|
120
112
|
websocket(): WebSocket.Server | undefined;
|
|
121
113
|
}
|
|
122
114
|
|
|
123
115
|
declare class Config {
|
|
124
116
|
static all(): Promise<TypeObjectString>;
|
|
125
117
|
static del(key: string): Promise<boolean>;
|
|
118
|
+
private static error;
|
|
126
119
|
static get(key: string): Promise<string>;
|
|
127
120
|
static set(key: string, value: string): Promise<void>;
|
|
128
121
|
}
|
|
129
122
|
|
|
130
|
-
declare
|
|
131
|
-
declare const API_DB_DATABASE: string;
|
|
132
|
-
declare const API_DB_HOST: string;
|
|
133
|
-
declare const API_DB_PASSWORD: string;
|
|
134
|
-
declare const API_DB_PORT: number;
|
|
135
|
-
declare const API_DB_TYPE: string;
|
|
136
|
-
declare const API_DB_USERNAME: string;
|
|
137
|
-
declare const API_DB_LOG: boolean;
|
|
138
|
-
declare const API_HTTP_CRT: string;
|
|
139
|
-
declare const API_HTTP_KEY: string;
|
|
140
|
-
declare const API_HTTP_PORT: number;
|
|
141
|
-
declare const API_HTTP_PUBLIC: string;
|
|
142
|
-
declare const API_HTTP_CROSS: boolean;
|
|
143
|
-
declare const API_HTTP_HYBRID: boolean;
|
|
144
|
-
declare const API_TOKEN_CRT: string;
|
|
145
|
-
declare const API_TOKEN_KEY: string;
|
|
146
|
-
declare const API_TOKEN_HEADER: string;
|
|
147
|
-
declare const API_TOKEN_LIFETIME: number;
|
|
148
|
-
declare const API_UPLOAD_COUNT: number;
|
|
149
|
-
declare const API_UPLOAD_FIELD: string;
|
|
150
|
-
declare const API_UPLOAD_SIZE: number;
|
|
151
|
-
declare const API_UPLOAD_TEMP: string;
|
|
152
|
-
declare const API_WEBSOCKET_START: boolean;
|
|
153
|
-
|
|
154
|
-
declare class AuthController extends Controller {
|
|
123
|
+
declare class AuthController extends ControllerBase {
|
|
155
124
|
readonly attributes: string[];
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
protected
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
125
|
+
protected login(res: Response, req: Request, useragent: string, app: Application): Promise<_andrewcaires_express.ResponseJson>;
|
|
126
|
+
protected logout(res: Response, req: Request, auth: Auth, user: User, app: Application): Promise<_andrewcaires_express.ResponseJson>;
|
|
127
|
+
protected user(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
declare class ForgotController extends ControllerBase {
|
|
131
|
+
check(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
|
|
132
|
+
forgot(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
|
|
133
|
+
reset(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
|
|
134
|
+
private findOne;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
type FnRecord<M> = (records: M) => any;
|
|
138
|
+
type FnRecords<M> = (records: Array<M>) => Array<any>;
|
|
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>;
|
|
143
|
+
error(error: any): void;
|
|
144
|
+
protected get(req: Request, res: Response, options?: FindOptions<Attributes<M>>, fn?: FnRecord<M>): Promise<_andrewcaires_express.ResponseJson>;
|
|
145
|
+
abstract model(): ModelStatic<M>;
|
|
171
146
|
protected name(): string;
|
|
172
|
-
protected set(
|
|
173
|
-
protected getModel(): ModelStatic<M> | undefined;
|
|
174
|
-
protected setModel(model: ModelStatic<M>): void;
|
|
147
|
+
protected set(req: Request, res: Response, options?: UpdateOptions<Attributes<M>>): Promise<_andrewcaires_express.ResponseJson>;
|
|
175
148
|
}
|
|
176
149
|
|
|
177
150
|
declare abstract class CrudController<M extends Model<M>> extends ModelController<M> {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
151
|
+
create(): TypeObject<ValidationBase>;
|
|
152
|
+
crudAdd(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
|
|
153
|
+
crudAll(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
|
|
154
|
+
crudDel(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
|
|
155
|
+
crudGet(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
|
|
156
|
+
crudSet(req: Request, res: Response): Promise<_andrewcaires_express.ResponseJson>;
|
|
157
|
+
optionsAdd(): CreateOptions<Attributes<M>>;
|
|
158
|
+
optionsAll(): FindOptions<Attributes<M>>;
|
|
159
|
+
optionsDel(): FindOptions<Attributes<M>>;
|
|
160
|
+
optionsGet(): FindOptions<Attributes<M>>;
|
|
161
|
+
optionsSet(): UpdateOptions<Attributes<M>>;
|
|
162
|
+
update(): TypeObject<ValidationBase>;
|
|
163
|
+
validationAdd(req: Request, res: Response, next: NextFunction): Promise<void | _andrewcaires_express.ResponseJson>;
|
|
164
|
+
validationSet(req: Request, res: Response, next: NextFunction): Promise<void | _andrewcaires_express.ResponseJson>;
|
|
182
165
|
}
|
|
183
166
|
|
|
184
167
|
declare class GroupController extends CrudController<Group> {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
168
|
+
model(): typeof Group;
|
|
169
|
+
create(): TypeObject<ValidationBase>;
|
|
170
|
+
update(): TypeObject<ValidationBase>;
|
|
188
171
|
}
|
|
189
172
|
|
|
190
173
|
declare class GroupRouteController extends ModelController<GroupRoute> {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
protected groupRouteSet(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
174
|
+
model(): typeof GroupRoute;
|
|
175
|
+
groupRouteAll(res: Response, req: Request, groupId: string): Promise<_andrewcaires_express.ResponseJson>;
|
|
176
|
+
groupRouteSet(res: Response, id: string, routes: Array<number>): Promise<_andrewcaires_express.ResponseJson>;
|
|
195
177
|
}
|
|
196
178
|
|
|
197
179
|
declare class LogsController extends ModelController<Logs> {
|
|
198
|
-
|
|
199
|
-
protected logsAll(
|
|
180
|
+
model(): typeof Logs;
|
|
181
|
+
protected logsAll(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
declare class RegisterController extends ControllerBase {
|
|
185
|
+
confirm(res: Response, token: string): Promise<_andrewcaires_express.ResponseJson>;
|
|
186
|
+
register(res: Response, req: Request, body: any, username: string): Promise<_andrewcaires_express.ResponseJson>;
|
|
200
187
|
}
|
|
201
188
|
|
|
202
189
|
declare class RouteController extends CrudController<Route> {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
190
|
+
model(): typeof Route;
|
|
191
|
+
create(): TypeObject<ValidationBase>;
|
|
192
|
+
update(): TypeObject<ValidationBase>;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
declare class SetupController extends ControllerBase {
|
|
196
|
+
protected setup(res: Response): Promise<_andrewcaires_express.ResponseJson>;
|
|
206
197
|
}
|
|
207
198
|
|
|
208
199
|
declare class UserController extends ModelController<User> {
|
|
209
|
-
private attributes;
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
protected
|
|
214
|
-
protected
|
|
215
|
-
protected
|
|
216
|
-
protected userGet(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
217
|
-
protected userSet(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
200
|
+
private readonly attributes;
|
|
201
|
+
model(): typeof User;
|
|
202
|
+
userAdd(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
|
|
203
|
+
protected userAll(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
|
|
204
|
+
protected userDel(res: Response, req: Request, user: User, id: string): Promise<_andrewcaires_express.ResponseJson>;
|
|
205
|
+
protected userGet(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
|
|
206
|
+
protected userSet(res: Response, req: Request): Promise<_andrewcaires_express.ResponseJson>;
|
|
218
207
|
}
|
|
219
208
|
|
|
220
209
|
declare class UserGroupController extends ModelController<UserGroup> {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
protected userGroupsSet(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
210
|
+
model(): typeof UserGroup;
|
|
211
|
+
userGroupsAll(res: Response, req: Request, userId: string): Promise<_andrewcaires_express.ResponseJson>;
|
|
212
|
+
userGroupsSet(res: Response, id: string, groups: Array<number>): Promise<_andrewcaires_express.ResponseJson>;
|
|
225
213
|
}
|
|
226
214
|
|
|
227
215
|
interface DatabaseOptions {
|
|
@@ -241,6 +229,47 @@ declare class Database {
|
|
|
241
229
|
}
|
|
242
230
|
declare const sequelize: Sequelize;
|
|
243
231
|
|
|
232
|
+
declare class Env {
|
|
233
|
+
static readonly API_CONSOLE_ERROR: boolean;
|
|
234
|
+
static readonly API_DB_DATABASE: string;
|
|
235
|
+
static readonly API_DB_HOST: string;
|
|
236
|
+
static readonly API_DB_PASSWORD: string;
|
|
237
|
+
static readonly API_DB_PORT: number;
|
|
238
|
+
static readonly API_DB_TYPE: string;
|
|
239
|
+
static readonly API_DB_USERNAME: string;
|
|
240
|
+
static readonly API_DB_LOG: boolean;
|
|
241
|
+
static readonly API_TABLE_PREFIX: string;
|
|
242
|
+
static readonly API_HTTP_CRT: string;
|
|
243
|
+
static readonly API_HTTP_KEY: string;
|
|
244
|
+
static readonly API_HTTP_PORT: number;
|
|
245
|
+
static readonly API_HTTP_PUBLIC: string;
|
|
246
|
+
static readonly API_HTTP_CROSS: boolean;
|
|
247
|
+
static readonly API_HTTP_HYBRID: boolean;
|
|
248
|
+
static readonly API_SLEEP_AUTH: number;
|
|
249
|
+
static readonly API_SLEEP_FORGOT: number;
|
|
250
|
+
static readonly API_SLEEP_REGISTRY: number;
|
|
251
|
+
static readonly API_TOKEN_CRT: string;
|
|
252
|
+
static readonly API_TOKEN_KEY: string;
|
|
253
|
+
static readonly API_TOKEN_HEADER: string;
|
|
254
|
+
static readonly API_TOKEN_LIFETIME: number;
|
|
255
|
+
static readonly API_UPLOAD_COUNT: number;
|
|
256
|
+
static readonly API_UPLOAD_FIELD: string;
|
|
257
|
+
static readonly API_UPLOAD_SIZE: number;
|
|
258
|
+
static readonly API_UPLOAD_TEMP: string;
|
|
259
|
+
static readonly API_WEBSOCKET_START: boolean;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
declare global {
|
|
263
|
+
namespace Express {
|
|
264
|
+
interface Request {
|
|
265
|
+
auth?: Auth;
|
|
266
|
+
user?: User;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
declare const ReqAuth: (key?: string | undefined) => ParameterDecorator;
|
|
271
|
+
declare const ReqUser: (key?: string | undefined) => ParameterDecorator;
|
|
272
|
+
|
|
244
273
|
declare class Log {
|
|
245
274
|
static write(message: string, source?: string, console?: boolean): Promise<void>;
|
|
246
275
|
static error(message: string, source?: string, console?: boolean): Promise<void>;
|
|
@@ -252,19 +281,9 @@ declare class Log {
|
|
|
252
281
|
}
|
|
253
282
|
|
|
254
283
|
declare class Permission {
|
|
255
|
-
static all(user: User, where?: WhereOptions): Promise<void | Route
|
|
256
|
-
static get(user: User): Promise<string
|
|
257
|
-
static is(user: User, name: string): Promise<boolean
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
declare class Responses {
|
|
261
|
-
static success(res: Response, message: string): Response<any, Record<string, any>>;
|
|
262
|
-
static data(res: Response, obj: object): Response<any, Record<string, any>>;
|
|
263
|
-
static error(res: Response, message: string): Response<any, Record<string, any>>;
|
|
264
|
-
static list(res: Response, arr: Array<any>): Response<any, Record<string, any>>;
|
|
265
|
-
static notfound(res: Response, message: string): Response<any, Record<string, any>>;
|
|
266
|
-
static validation(res: Response, message: string): Response<any, Record<string, any>>;
|
|
267
|
-
static unauthorized(res: Response, message: string): Response<any, Record<string, any>>;
|
|
284
|
+
static all(user: User, where?: WhereOptions): Promise<void | Array<Route>>;
|
|
285
|
+
static get(user: User): Promise<Array<string>>;
|
|
286
|
+
static is(user: User, name: string): Promise<boolean>;
|
|
268
287
|
}
|
|
269
288
|
|
|
270
289
|
declare const crt: {
|
|
@@ -290,9 +309,10 @@ interface TokenVerify {
|
|
|
290
309
|
decode?: TypeObject<string | number | boolean>;
|
|
291
310
|
}
|
|
292
311
|
declare class Token {
|
|
312
|
+
private static error;
|
|
293
313
|
static sign(payload: TypeObject<string | number>): TokenSign;
|
|
294
314
|
static user(token: string): Promise<TokenUser>;
|
|
295
315
|
static verify(token: string): TokenVerify;
|
|
296
316
|
}
|
|
297
317
|
|
|
298
|
-
export {
|
|
318
|
+
export { Application, Auth, AuthController, Config, Configs, ControllerBase, CrudController, Database, Env, Forgot, ForgotController, Group, GroupController, GroupRoute, GroupRouteController, Log, Logs, LogsController, ModelController, Permission, RegisterController, ReqAuth, ReqUser, Route, RouteController, SetupController, Token, User, UserController, UserGroup, UserGroupController, crt, key, sequelize };
|
package/dist/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @andrewcaires/api
|
|
2
|
+
* @andrewcaires/api v3.0.0
|
|
3
3
|
* Simple api for small applications using express, jsonwebtoken, sequelize and websocket
|
|
4
|
-
* (c)
|
|
4
|
+
* (c) 2023 Andrew Caires
|
|
5
5
|
* @license: MIT
|
|
6
6
|
*/
|
|
7
|
-
import{toBool as e,dateFormat as t,EventEmitter as r,sleep as s,Validation as i,uuidv4 as n,uniqueID as o,allowedObject as a,isArray as d,isString as u,noop as c}from"@andrewcaires/utils.js";import l from"cors";import h,{Router as p,json as m,urlencoded as v}from"express";import{existsSync as g,readFileSync as f}from"fs";import*as y from"http";import*as w from"https";import{Server as I}from"net";import b from"ws";import{config as _}from"dotenv";import{Sequelize as S,DataTypes as A,Model as T,Op as E}from"sequelize";import{sign as O,verify as R}from"jsonwebtoken";import N from"mime-types";import P from"multer";import{join as q}from"path";import{SHA256 as k}from"crypto-js";function x(e,t,r,s){return new(r||(r=Promise))((function(i,n){function o(e){try{d(s.next(e))}catch(e){n(e)}}function a(e){try{d(s.throw(e))}catch(e){n(e)}}function d(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,a)}d((s=s.apply(e,t||[])).next())}))}_();const z=parseInt(process.env.API_AUTH_SLEEP||"1000"),D=process.env.API_DB_DATABASE||"",G=process.env.API_DB_HOST||"127.0.0.1",j=process.env.API_DB_PASSWORD||"",B=parseInt(process.env.API_DB_PORT||"3306"),C=process.env.API_DB_TYPE||"",M=process.env.API_DB_USERNAME||"root",L=e(process.env.API_DB_LOG||"false"),U=process.env.API_HTTP_CRT||"",H=process.env.API_HTTP_KEY||"",K=parseInt(process.env.API_HTTP_PORT||"3000"),F=process.env.API_HTTP_PUBLIC||"",W=e(process.env.API_HTTP_CROSS||"false"),X=e(process.env.API_HTTP_HYBRID||"false"),Y=process.env.API_TOKEN_CRT||"",J=process.env.API_TOKEN_KEY||"",$=process.env.API_TOKEN_HEADER||"authorization",Z=parseInt(process.env.API_TOKEN_LIFETIME||"15"),Q=parseInt(process.env.API_UPLOAD_COUNT||"1"),V=process.env.API_UPLOAD_FIELD||"upload",ee=parseInt(process.env.API_UPLOAD_SIZE||"2"),te=process.env.API_UPLOAD_TEMP||"./temp",re=e(process.env.API_WEBSOCKET_START||"false");class se{static connect(e){const t=C.toLowerCase();if("connect_"+t in se)return se["connect_"+t](e);throw new Error("No database is connected to this API")}static connect_mariadb(e){return new S(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mariadb",logging:L,define:{timestamps:!1}})}static connect_memory(){return new S("sqlite::memory:",{logging:L,define:{timestamps:!1}})}static connect_mysql(e){return new S(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"mysql",logging:L,define:{timestamps:!1}})}static connect_postgres(e){return new S(e.database,e.username,e.password,{host:e.hostname,port:e.hostport,dialect:"postgres",logging:L,define:{timestamps:!1}})}static connect_sqlite(e){return new S({dialect:"sqlite",storage:e.database,logging:L,define:{timestamps:!1}})}}const ie=se.connect({database:D,username:M,password:j,hostname:G,hostport:B});class ne extends T{}ne.init({login:A.BIGINT,logout:A.BIGINT,secret:A.STRING,timestamp:A.BIGINT,useragent:A.STRING},{sequelize:ie,modelName:"auth"});class oe extends T{}oe.init({name:A.STRING,description:A.TEXT,state:A.BOOLEAN},{sequelize:ie,modelName:"group"});class ae extends T{}ae.init({name:A.STRING,description:A.TEXT,state:A.BOOLEAN},{sequelize:ie,modelName:"route"});class de extends T{}de.init({},{sequelize:ie,modelName:"groups_routes"}),de.removeAttribute("id");class ue extends T{}ue.init({name:A.STRING,email:A.STRING,username:A.STRING,password:A.STRING,description:A.TEXT,state:A.BOOLEAN},{sequelize:ie,modelName:"user"});class ce extends T{}ce.init({},{sequelize:ie,modelName:"users_groups"}),ce.removeAttribute("id");class le extends T{}le.init({key:A.STRING,value:A.STRING},{sequelize:ie,modelName:"configs",timestamps:!0,createdAt:"created",updatedAt:"updated"}),le.removeAttribute("id");class he extends T{}var pe;he.init({type:A.STRING,source:A.STRING,message:A.TEXT},{sequelize:ie,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1}),ue.hasMany(ne),ne.belongsTo(ue),oe.hasMany(de),de.belongsTo(oe),ae.hasMany(de),de.belongsTo(ae),ue.hasMany(ce),ce.belongsTo(ue),oe.hasMany(ce),ce.belongsTo(oe),function(e){e.ERROR="[31m",e.INFO="[36m",e.NONE="[37m",e.SUCCESS="[32m",e.WARNING="[33m"}(pe||(pe={}));class me{static write(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.NONE,"",e,t,r)}))}static error(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.ERROR,"error",e,t,r)}))}static info(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.INFO,"info",e,t,r)}))}static success(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.ERROR,"success",e,t,r)}))}static warning(e,t,r){return x(this,void 0,void 0,(function*(){yield me.writeRaw(pe.WARNING,"warning",e,t,r)}))}static writeConsole(e,r,s){const i=t(new Date,"%H:%M:%S");console.log(">",e,r+" ".repeat(10-r.length),"[37m","|",i,"|",s)}static writeRaw(e,t,r,s,i){return x(this,void 0,void 0,(function*(){i&&me.writeConsole(e,t,r),ie&&(yield he.create({type:t,source:s,message:r}).catch((()=>null)))}))}}class ve{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t){return e.status(400).json({message:t})}static unauthorized(e,t){return e.status(401).json({message:t})}}const ge=e=>g(e)?f(e):void 0,fe={http:ge(U),token:ge(Y)},ye={http:ge(H),token:ge(J)};class we{static sign(e){return ye.token?{token:O(e,ye.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static user(e){return x(this,void 0,void 0,(function*(){const{error:t,decode:r}=we.verify(e);if(t)return{error:t};if(r){const{id:e,secret:t}=r;if(e&&r){const r=yield ue.findOne({where:{id:e,state:!0}}).catch((e=>{me.error(e.message,"api.token",!0)}));if(r){const e=yield ne.findOne({where:{secret:t,userId:r.id}}).catch((e=>{me.error(e.message,"api.token",!0)}));if(e){const t=Date.now();if(t>e.timestamp)return{error:"Expired token"};if(e.timestamp=t+6e4*Z,yield e.save(),!e.logout)return{auth:e,user:r}}}return{error:"Access denied"}}}return{error:"Invalid token"}}))}static verify(e){if(!fe.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:R(e,fe.token)}}catch(e){return{error:"Invalid Token"}}}}class Ie extends r{constructor(e){super(),this.app=h(),this.router=p(),this.middlewares(),this.controllers(e)}controllers(e){e.forEach((e=>{e.intialize(),this.router.use(e.path(),e.router)}))}listen(){return x(this,void 0,void 0,(function*(){if(yield ie.sync(),fe.http&&ye.http||(this._server=y.createServer(this.app),this._server.listen(K,(()=>me.info("Server started on port "+K,"api.server",!0)))),!this._server){const e=y.createServer(((e,t)=>{const r=80==K?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),t=w.createServer({key:ye.http,cert:fe.http},this.app);if(X){new I((r=>{r.once("data",(s=>{r.pause(),r.unshift(s),(22===s[0]?t:e).emit("connection",r),process.nextTick((()=>r.resume()))}))})).listen(K,(()=>me.info("Server started on port "+K,"api.server",!0))),this._server=t}this._server||(443==K&&e.listen(80,(()=>me.info("Server started on port 80","api.server",!0))),t.listen(K,(()=>me.info("Server started on port "+K,"api.server",!0))),this._server=t)}re&&this._server&&(this._webSocket=new b.Server({server:this._server,verifyClient:(e,t)=>t(re)}),this._webSocket.on("connection",((e,t)=>x(this,void 0,void 0,(function*(){t.url||(t.url="");const r=t.url.length<=1?"":t.url.replace(/\//g,".");let i;e.on("message",(s=>x(this,void 0,void 0,(function*(){if(i)try{const n=JSON.parse(s);this.emit("ws.message"+r,{data:n,message:s,req:t,user:i,ws:e})}catch(n){this.emit("ws.message"+r,{message:s,req:t,user:i,ws:e})}else{const{user:n}=yield we.user(s.toString());n&&(i=n,this.emit("ws.connection"+r,{req:t,user:i,ws:e}))}i||e.close()})))),e.on("close",(()=>{i&&this.emit("ws.close"+r,{user:i,ws:e})})),yield s(2e3),i||e.close()})))))}))}middlewares(){this.app.use(m()),this.app.use(((e,t,r,s)=>e?(me.error(e.message,"api.express",!0),ve.error(r,"Internal Server Error")):s())),this.app.use(v({extended:!0})),this.app.disable("x-powered-by"),W&&this.app.use(l()),this.app.use("/api",this.router),this.app.all("/api/*",((e,t)=>ve.notfound(t,"Invalid API"))),F&&(g(F)&&this.app.use(h.static(F)),this.app.get("*",((e,t)=>{if(!g(F))return ve.notfound(t,'File "index.html" not found');t.sendFile(F+"/index.html")})))}server(){return this._server}websocket(){return this._webSocket}}class be{static all(){return x(this,void 0,void 0,(function*(){const e=yield le.findAll().catch((e=>{me.error(e.message,"api.config",!0)})),t={};return e&&e.forEach((e=>{t[e.key]=e.value})),t}))}static del(e){return x(this,void 0,void 0,(function*(){return((yield le.destroy({where:{key:e}}).catch((e=>{me.error(e.message,"api.config",!0)})))||0)>0}))}static get(e){return x(this,void 0,void 0,(function*(){const t=yield le.findOne({where:{key:e}}).catch((e=>{me.error(e.message,"api.config",!0)}));return t&&t.value||""}))}static set(e,t){return x(this,void 0,void 0,(function*(){const[r]=(yield le.findOrCreate({where:{key:e}}).catch((e=>{me.error(e.message,"api.config",!0)})))||[];r&&(r.value=t,yield r.save().catch((e=>{me.error(e.message,"api.config",!0)})))}))}}class _e{static all(e,t){return x(this,void 0,void 0,(function*(){return yield ae.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:de,required:!0,include:[{model:oe,required:!0,where:{state:!0},include:[{model:ce,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{me.error(e.message,"api.permission",!0)}))}))}static get(e){return x(this,void 0,void 0,(function*(){const t=yield _e.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return x(this,void 0,void 0,(function*(){const r=yield _e.all(e,{name:t});return r&&!!r.length}))}}const Se=(e,t)=>{const r=n()+"."+t;return g(q(e,r))?Se(e,t):r};class Ae{constructor(e){this.router=p(),this._path=e}auth(e,t,r){return x(this,void 0,void 0,(function*(){const s=e.get($)||"",{auth:i,error:n,user:o}=yield we.user(s);if(n)return ve.error(t,n);if(i&&o){const t=e.get("User-Agent");return t&&(i.useragent=t),yield i.save(),e.auth=i,e.user=o,r()}return ve.error(t,"Internal Server Error")}))}intialize(){}name(){return"api"}path(){return this._path}permission(e){return(t,r,s)=>x(this,void 0,void 0,(function*(){const i=t.user;return i?(yield _e.is(i,e))?s():ve.error(r,"Unauthorized access"):ve.unauthorized(r,"Access denied")}))}read(e=""){return this.permission((e||this.name())+".read")}upload(e){const t=(null==e?void 0:e.path)||te,r=P.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>x(this,void 0,void 0,(function*(){return s(null,Se(t,N.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||ee),i=P({storage:r,fileFilter(t,r,s){var i;return x(this,void 0,void 0,(function*(){const t=null===(i=null==e?void 0:e.types)||void 0===i?void 0:i.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),n=(null==e?void 0:e.count)||Q,o=(null==e?void 0:e.field)||V,a=i.array(o,n);return(e,t,r)=>{a(e,t,(function(e){return e?ve.error(t,e.message):r()}))}}validation(e){return(t,r,s)=>x(this,void 0,void 0,(function*(){const{error:n,value:o}=yield i.object(e).validateAsync(t.body);return n?ve.validation(r,n):(t.body=o,s())}))}write(e=""){return this.permission((e||this.name())+".write")}}class Te extends Ae{constructor(){super(...arguments),this.attributes=["id","name","email","username"],this.query={username:i.string().min(4).required(),password:i.string().min(5).required()}}intialize(){this.router.get("/",this.auth,this.user.bind(this)),this.router.post("/login",this.validation(this.query),this.login.bind(this)),this.router.get("/logout",this.auth,this.logout.bind(this))}login(e,t){return x(this,void 0,void 0,(function*(){yield s(z);const{username:r,password:i}=e.body,n=yield ue.findOne({where:{username:r}}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));if(!n)return ve.notfound(t,"Username not found");if(!n.state)return ve.error(t,"Username is disabled");const a=k(i).toString();if(n.password!=a)return ve.error(t,"Invalid password");const d=n.id,u=o(),{error:c,token:l}=we.sign({id:d,secret:u});if(c)return ve.error(t,c);if(l){const r=Date.now(),s=r+6e4*Z,i=e.get("User-Agent"),n=yield ne.create({login:r,secret:u,timestamp:s,useragent:i,userId:d}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));if(n)return ve.data(t,{token:l})}return ve.error(t,"Internal Server Error")}))}logout(e,t){return x(this,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),ve.success(t,"Disconcerted")):ve.unauthorized(t,"Access denied")}))}user(e,t){return x(this,void 0,void 0,(function*(){const r=e.user;if(!r)return ve.unauthorized(t,"Access denied");const s=yield _e.all(r);if(s){const e=a(this.attributes,r.toJSON()),i=s.map((e=>e.name));return ve.data(t,Object.assign(Object.assign({},e),{permissions:i}))}return ve.error(t,"Internal Server Error")}))}}class Ee extends Ae{add(){return(e,t)=>x(this,void 0,void 0,(function*(){if(!this._model)return ve.error(t,"Internal Server Error");const r=yield this._model.create(e.body).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));return r?ve.data(t,{id:r.id}):ve.error(t,"Internal Server Error")}))}all(e,t){return(r,s)=>x(this,void 0,void 0,(function*(){var i,n,o,a,l;if(!this._model)return ve.error(s,"Internal Server Error");const h=Object.assign({},e||{});h.where=Object.assign({},h.where||{});const p=null===(i=r.query.limit)||void 0===i?void 0:i.toString();p&&(h.limit=parseInt(p));const m=null===(n=r.query.offset)||void 0===n?void 0:n.toString();m&&(h.offset=parseInt(m));const v=Object.keys(this._model.getAttributes()),g=[],f=null===(o=r.query.asc)||void 0===o?void 0:o.toString();f&&f.length&&f.split(",").forEach((e=>{v.indexOf(e)>=0&&g.push([e,"ASC"])}));const y=null===(a=r.query.desc)||void 0===a?void 0:a.toString();y&&y.length&&y.split(",").forEach((e=>{v.indexOf(e)>=0&&g.push([e,"DESC"])})),g.length&&(h.order=g);const w=[],I=d(h.attributes)?h.attributes:v,b=null===(l=r.query.search)||void 0===l?void 0:l.toString();I.forEach((e=>{var t;if(u(e)&&(b&&b.length&&w.push({[e]:{[E.like]:`%${b}%`}}),"search_"+e in r.query)){const s=null===(t=r.query["search_"+e])||void 0===t?void 0:t.toString();s&&s.length&&w.push({[e]:{[E.like]:`%${s}%`}})}})),w.length&&(h.where=Object.assign(Object.assign({},h.where),{[E.or]:[...w]}));const _=yield this._model.findAll(h).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)})),S=yield this._model.count(h).catch(c);return _?ve.data(s,{count:S,records:t?t(_):_}):ve.error(s,"Internal Server Error")}))}del(){return(e,t)=>x(this,void 0,void 0,(function*(){if(!this._model)return ve.error(t,"Internal Server Error");const{id:r}=e.params;return(yield this._model.destroy({where:{id:r}}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)})))?ve.success(t,"OK"):ve.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>x(this,void 0,void 0,(function*(){if(!this._model)return ve.error(s,"Internal Server Error");e||(e={});const i=Object.assign({},e);i.where=i.where?Object.assign({},i.where):{};const{id:n}=r.params,o=yield this._model.findByPk(n,i).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));return o?ve.data(s,t?t(o):o.toJSON()):null===o?ve.notfound(s,"Record not found"):ve.error(s,"Internal Server Error")}))}name(){var e;return this._model?null===(e=this._model)||void 0===e?void 0:e.tableName:super.name()}set(){return(e,t)=>x(this,void 0,void 0,(function*(){if(!this._model)return ve.error(t,"Internal Server Error");const{id:r}=e.params,[s]=(yield this._model.update(e.body,{where:{id:r}}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)})))||[];return s?ve.success(t,"OK"):ve.success(t,"Record not changed")}))}getModel(){return this._model}setModel(e){this._model=e}}class Oe extends Ee{intialize(){const e=this.model();e&&this.setModel(e),this.router.use(this.auth),this.router.get("/",this.read(),this.all().bind(this)),this.router.post("/",this.write(),this.validation(this.create()),this.add().bind(this)),this.router.route("/:id").get(this.read(),this.get().bind(this)).put(this.write(),this.validation(this.update()),this.set().bind(this)).delete(this.write(),this.del().bind(this))}}class Re extends Oe{create(){return{name:i.string().required(),description:i.string().empty(""),state:i.boolean().required()}}model(){return oe}update(){return{name:i.string().empty(),description:i.string().empty(),state:i.boolean().empty()}}}class Ne extends Ee{constructor(){super(...arguments),this.groups={groups:i.array().items(i.number())}}intialize(){this.setModel(de),this.router.use(this.auth),this.router.route("/:id/groups").get(this.read("users"),this.groupRouteAll.bind(this)).put(this.write("users"),this.validation(this.groups),this.groupRouteSet.bind(this))}groupRouteAll(e,t){return x(this,void 0,void 0,(function*(){const{id:r}=e.params;return this.all({where:{groupId:r},include:[{model:ae,required:!0}]},(e=>e.map((e=>e.route))))(e,t)}))}groupRouteSet(e,t){return x(this,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,i=yield oe.findByPk(r,{attributes:["id"]}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));if(i){const e=i.id;if(yield de.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield ae.count({where:{id:s[r]}}),t&&(yield de.create({groupId:e,routeId:s[r]}))}return ve.success(t,"OK")}return null===i?ve.notfound(t,"Record not found"):ve.error(t,"Internal Server Error")}))}}class Pe extends Ee{intialize(){this.setModel(he),this.router.use(this.auth),this.router.get("/",this.read("logs"),this.logsAll.bind(this))}logsAll(e,t){return x(this,void 0,void 0,(function*(){const{source:r,type:s}=e.query,i=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return this.all({where:i,order:[["created","DESC"]]})(e,t)}))}}class qe extends Oe{create(){return{name:i.string().required(),description:i.string().empty(""),state:i.boolean().required()}}model(){return ae}update(){return{name:i.string().empty(),description:i.string().empty(),state:i.boolean().empty()}}}class ke extends Ee{constructor(){super(...arguments),this.attributes=["id","name","email","username","description","state"],this.create={name:i.string().required(),email:i.string().email().required(),username:i.string().min(4).required(),password:i.string().min(5).required(),description:i.string().required(),state:i.boolean().required()},this.update={name:i.string().empty(),email:i.string().email().empty(),username:i.string().min(4).empty(),password:i.string().min(5).empty(),description:i.string().empty(),state:i.boolean().empty()}}intialize(){this.setModel(ue),this.router.use(this.auth),this.router.get("/",this.read(),this.userAll.bind(this)),this.router.post("/",this.write(),this.validation(this.create),this.userAdd.bind(this)),this.router.route("/:id").get(this.read(),this.userGet.bind(this)).put(this.write(),this.validation(this.update),this.userSet.bind(this)).delete(this.write(),this.userDel.bind(this))}userAdd(e,t){return x(this,void 0,void 0,(function*(){return e.body.password=k(e.body.password).toString(),yield this.add()(e,t)}))}userAll(e,t){return x(this,void 0,void 0,(function*(){return this.all({attributes:this.attributes})(e,t)}))}userDel(e,t){return x(this,void 0,void 0,(function*(){const r=e.user;if(r){const{id:s}=e.params;if(r.id.toString()!=s)return this.del()(e,t)}return ve.error(t,"Internal Server Error")}))}userGet(e,t){return x(this,void 0,void 0,(function*(){return this.get({attributes:this.attributes})(e,t)}))}userSet(e,t){return x(this,void 0,void 0,(function*(){return e.body.password&&(e.body.password=k(e.body.password).toString()),this.set()(e,t)}))}}class xe extends Ee{constructor(){super(...arguments),this.groups={groups:i.array(i.number())}}intialize(){this.setModel(ce),this.router.use(this.auth),this.router.route("/:id/groups").get(this.read("groups"),this.userGroupsAll.bind(this)).put(this.write("groups"),this.validation(this.groups),this.userGroupsSet.bind(this))}userGroupsAll(e,t){return x(this,void 0,void 0,(function*(){const{id:r}=e.params;return this.all({where:{userId:r},include:[{model:oe,required:!0}]},(e=>e.map((e=>e.group))))(e,t)}))}userGroupsSet(e,t){return x(this,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,i=yield ue.findByPk(r,{attributes:["id"]}).catch((e=>{me.error(e.message,"api.controller."+this.name(),!0)}));if(i){if(yield ce.destroy({where:{userId:i.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield oe.count({where:{id:s[t]}}),e&&(yield ce.create({userId:i.id,groupId:s[t]}))}return ve.success(t,"OK")}return ve.notfound(t,"Record not found")}))}}export{z as API_AUTH_SLEEP,D as API_DB_DATABASE,G as API_DB_HOST,L as API_DB_LOG,j as API_DB_PASSWORD,B as API_DB_PORT,C as API_DB_TYPE,M as API_DB_USERNAME,W as API_HTTP_CROSS,U as API_HTTP_CRT,X as API_HTTP_HYBRID,H as API_HTTP_KEY,K as API_HTTP_PORT,F as API_HTTP_PUBLIC,Y as API_TOKEN_CRT,$ as API_TOKEN_HEADER,J as API_TOKEN_KEY,Z as API_TOKEN_LIFETIME,Q as API_UPLOAD_COUNT,V as API_UPLOAD_FIELD,ee as API_UPLOAD_SIZE,te as API_UPLOAD_TEMP,re as API_WEBSOCKET_START,Ie as App,ne as Auth,Te as AuthController,be as Config,le as Configs,Ae as Controller,Oe as CrudController,se as Database,oe as Group,Re as GroupController,de as GroupRoute,Ne as GroupRouteController,me as Log,he as Logs,Pe as LogsController,Ee as ModelController,_e as Permission,ve as Responses,ae as Route,qe as RouteController,we as Token,ue as User,ke as UserController,ce as UserGroup,xe as UserGroupController,fe as crt,ye as key,ie as sequelize};
|
|
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 A,Validation as I,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 D}from"sequelize";import{config as F}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())}))}F();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=Y.API_DB_TYPE.toLowerCase();if("connect_"+t in W)return W["connect_"+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="[31m",e.INFO="[36m",e.NONE="[37m",e.SUCCESS="[32m",e.WARNING="[33m"}(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),"[37m","|",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 A{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 I.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:I.string().min(4).required(),password:I.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:I.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:I.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:I.string().required(),password:I.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 Ae 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,A=null===(u=e.query.search)||void 0===u?void 0:u.toString();_.forEach((t=>{var r;if(T(t)&&(A&&A.length&&O.push({[t]:{[D.like]:`%${A}%`}}),"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]:{[D.like]:`%${n}%`}})}})),O.length&&(l.where=Object.assign(Object.assign({},l.where),{[D.or]:[...O]}));const I=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:I,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){super.error(e),e.sql&&oe.error(e.sql,"api.controller.sql",Y.API_CONSOLE_ERROR)}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 Ie extends Ae{create(){return{}}crudAdd(e,t){return this.add(e,t,this.optionsAdd())}crudAll(e,t){return this.all(e,t,this.optionsAll())}crudDel(e,t){return this.del(e,t,this.optionsDel())}crudGet(e,t){return this.get(e,t,this.optionsGet())}crudSet(e,t){return this.set(e,t,this.optionsSet())}optionsAdd(){return{}}optionsAll(){return{}}optionsDel(){return{}}optionsGet(){return{}}optionsSet(){return{where:{}}}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)],Ie.prototype,"crudAdd",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)],Ie.prototype,"crudAll",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)],Ie.prototype,"crudDel",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)],Ie.prototype,"crudGet",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)],Ie.prototype,"crudSet",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)],Ie.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)],Ie.prototype,"validationSet",null);let fe=class extends Ie{model(){return Q}create(){return{name:I.string().required(),description:I.string().empty(""),state:I.boolean().parse().required()}}update(){return{name:I.string().empty(),description:I.string().empty(),state:I.boolean().parse().empty()}}};fe=H([p("/groups")],fe);let Pe=class extends Ae{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:I.array(I.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 Ae{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:I.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:I.string().required(),email:I.string().email().required(),username:I.string().min(4).required(),password:I.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 Ie{model(){return V}create(){return{name:I.string().required(),description:I.string().empty(""),state:I.boolean().parse().required()}}update(){return{name:I.string().empty(),description:I.string().empty(),state:I.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 Ae{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:I.string().required(),email:I.string().email().required(),username:I.string().min(4).required(),password:I.string().min(5).required(),description:I.string().required(),state:I.boolean().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:I.string().empty(),email:I.string().email().empty(),username:I.string().min(4).empty(),password:I.string().min(5).empty(),description:I.string().empty(),state:I.boolean().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 Ae{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:I.array(I.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,Ie 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,Ae 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
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Simple api for small applications using express, jsonwebtoken, sequelize and websocket",
|
|
5
5
|
"main": "./dist/index.cjs.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -45,38 +45,39 @@
|
|
|
45
45
|
},
|
|
46
46
|
"homepage": "https://github.com/andrewcaires/npm/tree/main/api#readme",
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@andrewcaires/
|
|
48
|
+
"@andrewcaires/express": "^1.0.3",
|
|
49
|
+
"@andrewcaires/utils.js": "^0.2.10",
|
|
49
50
|
"cors": "^2.8.5",
|
|
50
51
|
"crypto-js": "^4.1.1",
|
|
51
52
|
"dotenv": "^16.0.3",
|
|
52
53
|
"express": "^4.18.2",
|
|
53
|
-
"jsonwebtoken": "^
|
|
54
|
-
"mariadb": "^3.0
|
|
54
|
+
"jsonwebtoken": "^9.0.0",
|
|
55
|
+
"mariadb": "^3.1.0",
|
|
55
56
|
"mime-types": "^2.1.35",
|
|
56
57
|
"multer": "^1.4.5-lts.1",
|
|
57
|
-
"mysql2": "^2.
|
|
58
|
-
"sequelize": "^6.
|
|
59
|
-
"ws": "^8.
|
|
58
|
+
"mysql2": "^3.2.0",
|
|
59
|
+
"sequelize": "^6.29.1",
|
|
60
|
+
"ws": "^8.12.1"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
|
-
"@rollup/plugin-commonjs": "^
|
|
63
|
-
"@rollup/plugin-terser": "^0.
|
|
64
|
-
"@rollup/plugin-typescript": "^
|
|
65
|
-
"@types/cors": "^2.8.
|
|
63
|
+
"@rollup/plugin-commonjs": "^24.0.1",
|
|
64
|
+
"@rollup/plugin-terser": "^0.4.0",
|
|
65
|
+
"@rollup/plugin-typescript": "^11.0.0",
|
|
66
|
+
"@types/cors": "^2.8.13",
|
|
66
67
|
"@types/crypto-js": "^4.1.1",
|
|
67
|
-
"@types/express": "^4.17.
|
|
68
|
-
"@types/jsonwebtoken": "^
|
|
68
|
+
"@types/express": "^4.17.17",
|
|
69
|
+
"@types/jsonwebtoken": "^9.0.1",
|
|
69
70
|
"@types/mime-types": "^2.1.1",
|
|
70
71
|
"@types/multer": "^1.4.7",
|
|
71
|
-
"@types/node": "^18.
|
|
72
|
-
"@types/ws": "^8.5.
|
|
73
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
74
|
-
"@typescript-eslint/parser": "^5.
|
|
75
|
-
"eslint": "^8.
|
|
76
|
-
"rollup": "^3.
|
|
77
|
-
"rollup-plugin-dts": "^5.
|
|
72
|
+
"@types/node": "^18.14.6",
|
|
73
|
+
"@types/ws": "^8.5.4",
|
|
74
|
+
"@typescript-eslint/eslint-plugin": "^5.54.1",
|
|
75
|
+
"@typescript-eslint/parser": "^5.54.1",
|
|
76
|
+
"eslint": "^8.35.0",
|
|
77
|
+
"rollup": "^3.18.0",
|
|
78
|
+
"rollup-plugin-dts": "^5.2.0",
|
|
78
79
|
"ts-node": "^10.9.1",
|
|
79
80
|
"ts-node-dev": "^2.0.0",
|
|
80
|
-
"tslib": "^2.
|
|
81
|
+
"tslib": "^2.5.0"
|
|
81
82
|
}
|
|
82
83
|
}
|