@andrewcaires/api 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,13 +1,19 @@
1
+ /*!
2
+ * @andrewcaires/api v1.0.3
3
+ * (c) 2022 Andrew Caires
4
+ * @license: MIT
5
+ */
1
6
  /// <reference types="node" />
2
7
  import * as https from 'https';
3
8
  import * as http from 'http';
4
9
  import * as _sequelize from 'sequelize';
5
10
  import { Model, Sequelize, ModelStatic, FindOptions, Attributes } from 'sequelize';
6
11
  import * as express_serve_static_core from 'express-serve-static-core';
7
- import WebSocket from 'ws';
8
12
  import { Request, Response, NextFunction } from 'express';
9
- import { WhereOptions } from 'sequelize/types';
10
13
  import { ObjectSchema } from 'joi';
14
+ import { WhereOptions } from 'sequelize/types';
15
+ import { TypeObject } from '@andrewcaires/utils.js';
16
+ import WebSocket from 'ws';
11
17
 
12
18
  declare const initialize: () => void;
13
19
  declare const server: http.Server | https.Server;
@@ -95,9 +101,31 @@ declare class Logs extends Model {
95
101
  }
96
102
 
97
103
  declare const app: express_serve_static_core.Express;
98
-
99
104
  declare const router: express_serve_static_core.Router;
100
105
 
106
+ declare global {
107
+ namespace Express {
108
+ interface Request {
109
+ auth?: Auth;
110
+ user?: User;
111
+ }
112
+ }
113
+ }
114
+ declare const auth: (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
115
+
116
+ declare const permission: (name: string) => (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
117
+
118
+ interface UploadOptions {
119
+ count?: number;
120
+ field?: string;
121
+ path?: string;
122
+ size?: number;
123
+ types?: string[];
124
+ }
125
+ declare const upload: (options?: UploadOptions) => (req: Request, res: Response, next: NextFunction) => void;
126
+
127
+ declare const validation: (schema: ObjectSchema) => (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
128
+
101
129
  declare const uuid: {
102
130
  type: _sequelize.AbstractDataTypeConstructor;
103
131
  defaultValue: _sequelize.AbstractDataTypeConstructor;
@@ -115,8 +143,6 @@ declare const key: {
115
143
  token: Buffer | undefined;
116
144
  };
117
145
 
118
- declare const startSocket: (server: http.Server | https.Server) => WebSocket.Server;
119
-
120
146
  declare type FnRecord<M> = (records: M) => any;
121
147
  declare type FnRecords<M> = (records: Array<M>) => Array<any>;
122
148
  declare class Controller<M extends Model<M>> {
@@ -131,11 +157,11 @@ declare class Controller<M extends Model<M>> {
131
157
  }
132
158
 
133
159
  declare class Log {
134
- static write(message: string, source?: string): void;
135
- static error(message: string, source?: string): void;
136
- static info(message: string, source?: string): void;
137
- static success(message: string, source?: string): void;
138
- static warning(message: string, source?: string): void;
160
+ static write(message: string, source?: string, console?: boolean): void;
161
+ static error(message: string, source?: string, console?: boolean): void;
162
+ static info(message: string, source?: string, console?: boolean): void;
163
+ static success(message: string, source?: string, console?: boolean): void;
164
+ static warning(message: string, source?: string, console?: boolean): void;
139
165
  private static writeConsole;
140
166
  private static writeRaw;
141
167
  }
@@ -156,27 +182,19 @@ declare class Responses {
156
182
  static unauthorized(res: Response, message: string): Response<any, Record<string, any>>;
157
183
  }
158
184
 
159
- declare global {
160
- namespace Express {
161
- interface Request {
162
- auth: Auth | undefined;
163
- user: User | undefined;
164
- }
165
- }
185
+ interface TokenSign {
186
+ error?: string;
187
+ token?: string;
166
188
  }
167
- declare const auth: (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
168
-
169
- declare const permission: (name: string) => (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
170
-
171
- interface UploadOptions {
172
- count?: number;
173
- field?: string;
174
- path?: string;
175
- size?: number;
176
- types?: string[];
189
+ interface TokenVerify {
190
+ error?: string;
191
+ decode?: TypeObject<string | number | boolean>;
192
+ }
193
+ declare class Token {
194
+ static sign(payload: TypeObject<string | number>): TokenSign;
195
+ static verify(token: string): TokenVerify;
177
196
  }
178
- declare const upload: (options?: UploadOptions | undefined) => (req: Request, res: Response, next: NextFunction) => void;
179
197
 
180
- declare const validation: (schema: ObjectSchema) => (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
198
+ declare const startSocket: (server: http.Server | https.Server) => WebSocket.Server;
181
199
 
182
- export { API_AUTH_SLEEP, API_DB_DATABASE, API_DB_HOST, API_DB_LOG, API_DB_PASSWORD, API_DB_PORT, API_DB_TYPE, API_DB_USERNAME, API_HTTP_CROSS, API_HTTP_CRT, API_HTTP_HYBRID, API_HTTP_KEY, API_HTTP_PORT, API_HTTP_PUBLIC, API_TOKEN_CRT, API_TOKEN_HEADER, API_TOKEN_KEY, API_TOKEN_LIFETIME, API_UPLOAD_COUNT, API_UPLOAD_FIELD, API_UPLOAD_SIZE, API_UPLOAD_TEMP, API_WEBSOCKET_START, Auth, Controller, Group, GroupRoute, Log, Logs, Permission, Responses, Route, User, UserGroup, app, auth, crt, initialize, key, permission, router, sequelize, server, startSocket, upload, uuid, validation };
200
+ export { API_AUTH_SLEEP, API_DB_DATABASE, API_DB_HOST, API_DB_LOG, API_DB_PASSWORD, API_DB_PORT, API_DB_TYPE, API_DB_USERNAME, API_HTTP_CROSS, API_HTTP_CRT, API_HTTP_HYBRID, API_HTTP_KEY, API_HTTP_PORT, API_HTTP_PUBLIC, API_TOKEN_CRT, API_TOKEN_HEADER, API_TOKEN_KEY, API_TOKEN_LIFETIME, API_UPLOAD_COUNT, API_UPLOAD_FIELD, API_UPLOAD_SIZE, API_UPLOAD_TEMP, API_WEBSOCKET_START, Auth, Controller, Group, GroupRoute, Log, Logs, Permission, Responses, Route, Token, User, UserGroup, app, auth, crt, initialize, key, permission, router, sequelize, server, startSocket, upload, uuid, validation };
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * @andrewcaires/api v1.0.2
2
+ * @andrewcaires/api v1.0.3
3
3
  * (c) 2022 Andrew Caires
4
4
  * @license: MIT
5
5
  */
6
- import{toBool as e,forEachSeries as t,dateFormat as r,sleep as s,uniqueID as o,allowedObject as n,noop as i,uuidv4 as a}from"@andrewcaires/utils.js";import{config as d}from"dotenv";import{Sequelize as u,UUID as c,UUIDV4 as l,DataTypes as m,Model as p,Op as g}from"sequelize";import v from"cors";import f,{Router as h}from"express";import{existsSync as w,readFileSync as y}from"fs";import{SHA256 as I}from"crypto-js";import b from"jsonwebtoken";import S from"joi";import*as T from"http";import*as A from"https";import{Server as O}from"net";import E from"ws";import _ from"mime-types";import P from"multer";import{join as N}from"path";d();const R=parseInt(process.env.API_AUTH_SLEEP||"1000"),j=process.env.API_DB_DATABASE||"",q=process.env.API_DB_HOST||"127.0.0.1",k=process.env.API_DB_PASSWORD||"",D=parseInt(process.env.API_DB_PORT||"3306"),x=process.env.API_DB_TYPE||"",B=process.env.API_DB_USERNAME||"root",z=e(process.env.API_DB_LOG||"false"),G=process.env.API_HTTP_CRT||"",U=process.env.API_HTTP_KEY||"",C=parseInt(process.env.API_HTTP_PORT||"3000"),L=process.env.API_HTTP_PUBLIC||"",H=e(process.env.API_HTTP_CROSS||"false"),K=e(process.env.API_HTTP_HYBRID||"false"),M=process.env.API_TOKEN_CRT||"",F=process.env.API_TOKEN_KEY||"",W=process.env.API_TOKEN_HEADER||"authorization",X=parseInt(process.env.API_TOKEN_LIFETIME||"15"),Y=parseInt(process.env.API_UPLOAD_COUNT||"1"),$=process.env.API_UPLOAD_FIELD||"upload",J=parseInt(process.env.API_UPLOAD_SIZE||"2"),V=process.env.API_UPLOAD_TEMP||"./temp",Z=e(process.env.API_WEBSOCKET_START||"false");function Q(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())}))}const ee={type:c,defaultValue:l,allowNull:!1,primaryKey:!0},te=(()=>{switch(x){case"mariadb":return new u(j,B,k,{host:q,port:D,dialect:"mariadb",logging:z,define:{timestamps:!1}});case"mysql":return new u(j,B,k,{host:q,port:D,dialect:"mysql",logging:z,define:{timestamps:!1}});case"postgres":return new u(j,B,k,{host:q,port:D,dialect:"postgres",logging:z,define:{timestamps:!1}})}throw new Error("No database selected")})();class re extends p{}re.init({login:m.BIGINT,logout:m.BIGINT,secret:m.STRING,timestamp:m.BIGINT,useragent:m.STRING},{sequelize:te,modelName:"auth"});class se extends p{}se.init({name:m.STRING,description:m.TEXT,state:m.BOOLEAN},{sequelize:te,modelName:"group"});class oe extends p{}oe.init({type:m.STRING,source:m.STRING,message:m.TEXT},{sequelize:te,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1});class ne extends p{}ne.init({name:m.STRING,description:m.TEXT,state:m.BOOLEAN},{sequelize:te,modelName:"route"});class ie extends p{}ie.init({},{sequelize:te,modelName:"groups_routes"}),ie.removeAttribute("id");class ae extends p{}ae.init({name:m.STRING,email:m.STRING,username:m.STRING,password:m.STRING,description:m.TEXT,state:m.BOOLEAN},{sequelize:te,modelName:"user"});class de extends p{}de.init({},{sequelize:te,modelName:"users_groups"}),de.removeAttribute("id"),ae.hasMany(re),re.belongsTo(ae),se.hasMany(ie),ie.belongsTo(se),ne.hasMany(ie),ie.belongsTo(ne),ae.hasMany(de),de.belongsTo(ae),se.hasMany(de),de.belongsTo(se);var ue;!function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(ue||(ue={}));class ce{static write(e,t){ce.writeRaw(ue.NONE,"",e,t)}static error(e,t){ce.writeRaw(ue.ERROR,"error",e,t)}static info(e,t){ce.writeRaw(ue.INFO,"info",e,t)}static success(e,t){ce.writeRaw(ue.ERROR,"success",e,t)}static warning(e,t){ce.writeRaw(ue.WARNING,"warning",e,t)}static writeConsole(e,t,s){const o=r(new Date,"%H:%M:%S");console.log(">",e,t+" ".repeat(10-t.length),"","|",o,"|",s)}static writeRaw(e,t,r,s){ce.writeConsole(e,t,r),oe.create({type:t,source:s,message:r}).catch((()=>null))}}class le{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t,r){return e.status(400).json({message:t,details:r})}static unauthorized(e,t){return e.status(401).json({message:t})}}const me=e=>{if(w(e))return y(e)},pe={http:me(G),token:me(M)},ge={http:me(U),token:me(F)};class ve{static all(e,t){return Q(this,void 0,void 0,(function*(){return yield ne.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:ie,required:!0,include:[{model:se,required:!0,where:{state:!0},include:[{model:de,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{ce.error(e.message,"permission")}))}))}static get(e){return Q(this,void 0,void 0,(function*(){const t=yield ve.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return Q(this,void 0,void 0,(function*(){const r=yield ve.all(e,{name:t});return r&&!!r.length}))}}const fe=["id","name","email","username"],he=(e,t,r)=>Q(void 0,void 0,void 0,(function*(){const s=e.get(W)||"";if(!pe.token)return le.error(t,"Invalid Secret");if(!s||s.split(".").length<3)return le.error(t,"Invalid token");let o;try{o=b.verify(s,pe.token)}catch(e){return le.error(t,"Invalid token")}if(o&&o.id&&o.secret){const s=yield ae.findOne({where:{id:o.id}}).catch((e=>{ce.error(e.message,"token.check")}));if(s&&s.state){const n=yield re.findOne({where:{logout:null,secret:o.secret,userId:s.id}}).catch((e=>{ce.error(e.message,"token.check")}));if(n){const o=Date.now();if(o>n.timestamp)return le.error(t,"Expired token");n.timestamp=o+6e4*X;const i=e.get("User-Agent");return i&&(n.useragent=i),yield n.save(),e.auth=n,e.user=s,r()}}return le.error(t,"Access denied")}return le.error(t,"Invalid token")})),we=e=>{const t={abortEarly:!1,allowUnknown:!0,stripUnknown:!0};return(r,s,o)=>{const{error:n,value:i}=e.validate(r.body,t);if(n){const e=n.details.map((e=>e.message)).join(", "),t=[];return n.details.forEach((e=>{var r;t.push({key:(null===(r=e.context)||void 0===r?void 0:r.key)||"",type:e.type})})),le.validation(s,"Validation error: "+e,t)}return r.body=i,o()}},ye={username:S.string().min(5).required(),password:S.string().min(5).required()},Ie=we(S.object(ye)),be=h();be.get("/",he,((e,t)=>Q(void 0,void 0,void 0,(function*(){const r=e.user;if(!r)return le.unauthorized(t,"Access denied");const s=yield ve.all(r);if(s){const e=n(fe,r.toJSON()),o=s.map((e=>e.name));return le.data(t,Object.assign(Object.assign({},e),{permissions:o}))}return le.error(t,"Internal Server Error")})))),be.post("/login",Ie,((e,t)=>Q(void 0,void 0,void 0,(function*(){const{username:r,password:n}=e.body;if(!r||!n)return le.error(t,"Invalid parameters");yield s(R);const i=yield ae.findOne({where:{username:r}}).catch((e=>{ce.error(e.message,"auth.login")}));if(!i)return le.notfound(t,"User not found");if(!i.state)return le.error(t,"User is disabled");const a=I(n).toString();if(i.password!=a)return le.error(t,"Invalid password");if(!ge.token)return le.error(t,"Invalid Secret");const d=i.id,u=o(),c=b.sign({id:d,secret:u},ge.token,{algorithm:"RS256"});if(c){const r=Date.now(),s=r+6e4*X,o=e.get("User-Agent");if(yield re.create({login:r,secret:u,timestamp:s,useragent:o,userId:d}).catch((e=>{ce.error(e.message,"auth.login")})))return le.data(t,{token:c})}return le.error(t,"Internal Server Error")})))),be.get("/logout",he,((e,t)=>Q(void 0,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),le.success(t,"Disconcerted")):le.unauthorized(t,"Access denied")}))));class Se{constructor(e,t){this.log=e,this.model=t}add(){return(e,t)=>Q(this,void 0,void 0,(function*(){const r=yield this.model.create(e.body).catch((e=>{ce.error(e.message,this.log+".add")}));return r?le.data(t,{id:r.id}):le.error(t,"Internal Server Error")}))}all(e,t){return(r,s)=>Q(this,void 0,void 0,(function*(){var o,n,a,d,u;e||(e={});const c=Object.assign({},e);c.where=c.where?Object.assign({},c.where):{};const l=null===(o=r.query.limit)||void 0===o?void 0:o.toString();l&&(c.limit=parseInt(l));const m=null===(n=r.query.offset)||void 0===n?void 0:n.toString();m&&(c.offset=parseInt(m));const p=null===(a=r.query.asc)||void 0===a?void 0:a.toString();p&&(c.order=[[p,"ASC"]]);const v=null===(d=r.query.desc)||void 0===d?void 0:d.toString();v&&(c.order=[[v,"DESC"]]);const f=[],h=null===(u=r.query.search)||void 0===u?void 0:u.toString();h&&(Object.keys(this.model.getAttributes()).forEach((e=>{f.push({[e]:{[g.like]:`%${h}%`}})})),f.length&&(c.where=Object.assign(Object.assign({},c.where),{[g.or]:[...f]})));const w=yield this.model.findAll(c).catch((e=>{ce.error(e.message,this.log+".all")})),y=yield this.model.count(c).catch(i);return w?le.data(s,{count:y,records:t?t(w):w}):le.error(s,"Internal Server Error")}))}del(){return(e,t)=>Q(this,void 0,void 0,(function*(){const{id:r}=e.params;return(yield this.model.destroy({where:{id:r}}).catch((e=>{ce.error(e.message,this.log+".del")})))?le.success(t,"OK"):le.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>Q(this,void 0,void 0,(function*(){e||(e={});const o=Object.assign({},e);o.where=o.where?Object.assign({},o.where):{};const{id:n}=r.params,i=yield this.model.findByPk(n,o).catch((e=>{ce.error(e.message,this.log+".get")}));return i?le.data(s,t?t(i):i.toJSON()):null===i?le.notfound(s,"Record not found"):le.error(s,"Internal Server Error")}))}set(){return(e,t)=>Q(this,void 0,void 0,(function*(){const{id:r}=e.params,s=yield this.model.update(e.body,{where:{id:r}}).catch((e=>{ce.error(e.message,this.log+".set")}));if(s){const[e]=s;if(e)return le.success(t,"OK")}return le.success(t,"Record not changed")}))}}const Te=new Se("groups",se),Ae=new Se("groups.route",ie),Oe=Te.add(),Ee=Te.all(),_e=Te.del(),Pe=Te.get(),Ne=Te.set(),Re=e=>(t,r,s)=>Q(void 0,void 0,void 0,(function*(){const o=t.user;return o?(yield ve.is(o,e))?s():le.error(r,"Unauthorized access"):le.unauthorized(r,"Access denied")})),je={name:S.string().min(3).required(),description:S.string().allow(null,""),state:S.boolean().required()},qe=we(S.object(je)),ke={routes:S.array().items(S.number())},De=we(S.object(ke)),xe={name:S.string().min(3).empty(""),description:S.string().allow(null,""),state:S.boolean().empty("")},Be=we(S.object(xe)),ze=h();ze.use(he),ze.get("/",Re("groups.read"),Ee),ze.post("/",Re("groups.write"),qe,Oe),ze.route("/:id").get(Re("groups.read"),Pe).put(Re("groups.write"),Be,Ne).delete(Re("groups.write"),_e),ze.route("/:id/routes").get(Re("groups.read"),De,((e,t)=>Q(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return Ae.all({where:{groupId:r},include:[{model:ne,required:!0}]},(e=>e.map((e=>e.route))))(e,t)})))).put(Re("groups.write"),De,((e,t)=>Q(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,o=yield se.findByPk(r,{attributes:["id"]}).catch((e=>{ce.error(e.message,"groups.routesSet")}));if(o){const e=o.id;if(yield ie.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield ne.count({where:{id:s[r]}}),t&&(yield ie.create({groupId:e,routeId:s[r]}))}return le.success(t,"OK")}return null===o?le.notfound(t,"Record not found"):le.error(t,"Internal Server Error")}))));const Ge=new Se("route",ne),Ue=Ge.add(),Ce=Ge.all(),Le=Ge.del(),He=Ge.get(),Ke=Ge.set(),Me={name:S.string().min(5).required(),description:S.string().allow(null,""),state:S.boolean().required()},Fe=we(S.object(Me)),We={name:S.string().min(5).empty(""),description:S.string().allow(null,""),state:S.boolean().empty("")},Xe=we(S.object(We)),Ye=h();Ye.use(he),Ye.get("/",Re("routes.read"),Ce),Ye.post("/",Re("routes.write"),Fe,Ue),Ye.route("/:id").get(Re("routes.read"),He).put(Re("routes.write"),Xe,Ke).delete(Re("routes.write"),Le);const $e=new Se("user",ae),Je=new Se("user.groups",de),Ve=["id","name","email","username","description","state"],Ze=$e.del(),Qe={name:S.string().min(5).required(),email:S.string().email().required(),username:S.string().min(5).required(),password:S.string().min(5).required(),description:S.string().allow(null,""),state:S.boolean().required()},et=we(S.object(Qe)),tt={groups:S.array().items(S.number())},rt=we(S.object(tt)),st={name:S.string().min(5).empty(""),email:S.string().email().empty(""),username:S.string().min(5).empty(""),password:S.string().min(5).empty(""),description:S.string().allow(null,""),state:S.boolean().empty("")},ot=we(S.object(st)),nt=h();nt.use(he),nt.get("/",Re("users.read"),((e,t)=>Q(void 0,void 0,void 0,(function*(){return $e.all({attributes:Ve})(e,t)})))),nt.post("/",Re("users.write"),et,((e,t)=>Q(void 0,void 0,void 0,(function*(){return e.body.password=I(e.body.password).toString(),yield $e.add()(e,t)})))),nt.route("/:id").get(Re("users.read"),((e,t)=>Q(void 0,void 0,void 0,(function*(){return $e.get({attributes:Ve})(e,t)})))).put(Re("users.write"),ot,((e,t)=>Q(void 0,void 0,void 0,(function*(){return e.body.password&&(e.body.password=I(e.body.password).toString()),$e.set()(e,t)})))).delete(Re("users.write"),Ze),nt.route("/:id/groups").get(Re("users.read"),((e,t)=>Q(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return Je.all({where:{userId:r},include:[{model:se,required:!0}]},(e=>e.map((e=>e.group))))(e,t)})))).put(Re("users.write"),rt,((e,t)=>Q(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,o=yield ae.findByPk(r,{attributes:["id"]}).catch((e=>{ce.error(e.message,"user.groups.set")}));if(o){if(yield de.destroy({where:{userId:o.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield se.count({where:{id:s[t]}}),e&&(yield de.create({userId:o.id,groupId:s[t]}))}return le.success(t,"OK")}return le.notfound(t,"Record not found")}))));const it=h();it.use("/v1/auth",be),it.use("/v1/groups",ze),it.use("/v1/routes",Ye),it.use("/v1/users",nt);const at=f();at.use(f.json()),at.use(((e,t,r,s)=>e?(ce.error(e.message,"express"),le.error(r,"Internal Server Error")):s())),at.use(f.urlencoded({extended:!0})),at.disable("x-powered-by"),H&&at.use(v()),at.use("/api",it),at.all("/api/*",((e,t)=>le.notfound(t,"Invalid API"))),L&&(w(L)&&at.use(f.static(L)),at.get("*",((e,t)=>{if(!w(L))return le.notfound(t,'File "index.html" not found');t.sendFile(L+"/index.html")})));const dt=e=>{const t=new E.Server({server:e,verifyClient:ut});return t.on("connection",(e=>{e.on("message",(t=>{e.close()})),setTimeout((()=>{e.close()}),2e3),e.on("close",(()=>{t.emit("close",e)}))})),t},ut=(e,t)=>t(Z),ct=()=>{te.sync().then((()=>{Q(void 0,void 0,void 0,(function*(){if(0==(yield ae.count())){const e=yield ae.create({name:"Admin",email:"admin@localhost",username:"admin",password:"8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",description:"",state:!0});if(0==(yield se.count())){const r=yield se.create({name:"admin",description:"",state:!0});if(yield de.create({userId:e.id,groupId:r.id}),0==(yield ne.count())){const e=["read","write"];t(["users","groups","permission"],(s=>Q(void 0,void 0,void 0,(function*(){t(e,(e=>Q(void 0,void 0,void 0,(function*(){const t=s.toLowerCase()+"."+e.toLowerCase(),o=yield ne.create({name:t,description:"",state:!0});yield ie.create({groupId:r.id,routeId:o.id})}))))}))))}}}})),Z&&dt(lt)}))},lt=(e=>{if(!pe.http||!ge.http){const t=T.createServer(e);return t.listen(C,(()=>ce.info(`Server started on port ${C}`))),t}const t=T.createServer(((e,t)=>{const r=80==C?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),r=A.createServer({key:ge.http,cert:pe.http},e);if(K){return new O((e=>{e.once("data",(s=>{e.pause(),e.unshift(s),(22===s[0]?r:t).emit("connection",e),process.nextTick((()=>e.resume()))}))})).listen(C,(()=>ce.info(`Server started on port ${C}`))),r}return 443==C&&t.listen(80,(()=>ce.info("Server started on port 80"))),r.listen(C,(()=>ce.info(`Server started on port ${C}`))),r})(at),mt=(e,t)=>{const r=a()+"."+t;return w(N(e,r))?mt(e,t):r},pt=e=>{const t=(null==e?void 0:e.path)||V,r=P.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>Q(void 0,void 0,void 0,(function*(){return s(null,mt(t,_.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||J),o=P({storage:r,fileFilter(t,r,s){var o;return Q(this,void 0,void 0,(function*(){const t=null===(o=null==e?void 0:e.types)||void 0===o?void 0:o.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),n=(null==e?void 0:e.count)||Y,i=(null==e?void 0:e.field)||$,a=o.array(i,n);return(e,t,r)=>{a(e,t,(function(e){return e?le.error(t,e.message):r()}))}};export{R as API_AUTH_SLEEP,j as API_DB_DATABASE,q as API_DB_HOST,z as API_DB_LOG,k as API_DB_PASSWORD,D as API_DB_PORT,x as API_DB_TYPE,B as API_DB_USERNAME,H as API_HTTP_CROSS,G as API_HTTP_CRT,K as API_HTTP_HYBRID,U as API_HTTP_KEY,C as API_HTTP_PORT,L as API_HTTP_PUBLIC,M as API_TOKEN_CRT,W as API_TOKEN_HEADER,F as API_TOKEN_KEY,X as API_TOKEN_LIFETIME,Y as API_UPLOAD_COUNT,$ as API_UPLOAD_FIELD,J as API_UPLOAD_SIZE,V as API_UPLOAD_TEMP,Z as API_WEBSOCKET_START,re as Auth,Se as Controller,se as Group,ie as GroupRoute,ce as Log,oe as Logs,ve as Permission,le as Responses,ne as Route,ae as User,de as UserGroup,at as app,he as auth,pe as crt,ct as initialize,ge as key,Re as permission,it as router,te as sequelize,lt as server,dt as startSocket,pt as upload,ee as uuid,we as validation};
6
+ import{toBool as e,forEachSeries as t,dateFormat as r,isUndefined as s,noop as o,sleep as n,uniqueID as i,allowedObject as d,uuidv4 as a}from"@andrewcaires/utils.js";import{config as u}from"dotenv";import{Sequelize as c,UUID as l,UUIDV4 as m,DataTypes as p,Model as g,Op as v}from"sequelize";import f from"cors";import h,{Router as y}from"express";import{existsSync as w,readFileSync as I}from"fs";import{SHA256 as b}from"crypto-js";import{sign as S,verify as T}from"jsonwebtoken";import A from"mime-types";import O from"multer";import{join as E}from"path";import _ from"joi";import*as P from"http";import*as N from"https";import{Server as R}from"net";import j from"ws";u();const q=parseInt(process.env.API_AUTH_SLEEP||"1000"),k=process.env.API_DB_DATABASE||"",D=process.env.API_DB_HOST||"127.0.0.1",x=process.env.API_DB_PASSWORD||"",B=parseInt(process.env.API_DB_PORT||"3306"),z=process.env.API_DB_TYPE||"",G=process.env.API_DB_USERNAME||"root",U=e(process.env.API_DB_LOG||"false"),C=process.env.API_HTTP_CRT||"",L=process.env.API_HTTP_KEY||"",H=parseInt(process.env.API_HTTP_PORT||"3000"),K=process.env.API_HTTP_PUBLIC||"",M=e(process.env.API_HTTP_CROSS||"false"),F=e(process.env.API_HTTP_HYBRID||"false"),W=process.env.API_TOKEN_CRT||"",X=process.env.API_TOKEN_KEY||"",Y=process.env.API_TOKEN_HEADER||"authorization",$=parseInt(process.env.API_TOKEN_LIFETIME||"15"),J=parseInt(process.env.API_UPLOAD_COUNT||"1"),V=process.env.API_UPLOAD_FIELD||"upload",Z=parseInt(process.env.API_UPLOAD_SIZE||"2"),Q=process.env.API_UPLOAD_TEMP||"./temp",ee=e(process.env.API_WEBSOCKET_START||"false");function te(e,t,r,s){return new(r||(r=Promise))((function(o,n){function i(e){try{a(s.next(e))}catch(e){n(e)}}function d(e){try{a(s.throw(e))}catch(e){n(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,d)}a((s=s.apply(e,t||[])).next())}))}const re={type:l,defaultValue:m,allowNull:!1,primaryKey:!0},se=(()=>{switch(z){case"mariadb":return new c(k,G,x,{host:D,port:B,dialect:"mariadb",logging:U,define:{timestamps:!1}});case"mysql":return new c(k,G,x,{host:D,port:B,dialect:"mysql",logging:U,define:{timestamps:!1}});case"postgres":return new c(k,G,x,{host:D,port:B,dialect:"postgres",logging:U,define:{timestamps:!1}})}throw new Error("No database selected")})();class oe extends g{}oe.init({login:p.BIGINT,logout:p.BIGINT,secret:p.STRING,timestamp:p.BIGINT,useragent:p.STRING},{sequelize:se,modelName:"auth"});class ne extends g{}ne.init({name:p.STRING,description:p.TEXT,state:p.BOOLEAN},{sequelize:se,modelName:"group"});class ie extends g{}ie.init({type:p.STRING,source:p.STRING,message:p.TEXT},{sequelize:se,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1});class de extends g{}de.init({name:p.STRING,description:p.TEXT,state:p.BOOLEAN},{sequelize:se,modelName:"route"});class ae extends g{}ae.init({},{sequelize:se,modelName:"groups_routes"}),ae.removeAttribute("id");class ue extends g{}ue.init({name:p.STRING,email:p.STRING,username:p.STRING,password:p.STRING,description:p.TEXT,state:p.BOOLEAN},{sequelize:se,modelName:"user"});class ce extends g{}ce.init({},{sequelize:se,modelName:"users_groups"}),ce.removeAttribute("id"),ue.hasMany(oe),oe.belongsTo(ue),ne.hasMany(ae),ae.belongsTo(ne),de.hasMany(ae),ae.belongsTo(de),ue.hasMany(ce),ce.belongsTo(ue),ne.hasMany(ce),ce.belongsTo(ne);var le;!function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(le||(le={}));class me{static write(e,t,r){me.writeRaw(le.NONE,"",e,t,r)}static error(e,t,r){me.writeRaw(le.ERROR,"error",e,t,r)}static info(e,t,r){me.writeRaw(le.INFO,"info",e,t,r)}static success(e,t,r){me.writeRaw(le.ERROR,"success",e,t,r)}static warning(e,t,r){me.writeRaw(le.WARNING,"warning",e,t,r)}static writeConsole(e,t,s){const o=r(new Date,"%H:%M:%S");console.log(">",e,t+" ".repeat(10-t.length),"","|",o,"|",s)}static writeRaw(e,t,r,o,n){(n=!!s(n)||n)&&me.writeConsole(e,t,r),ie.create({type:t,source:o,message:r}).catch((()=>null))}}class pe{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t,r){return e.status(400).json({message:t,details:r})}static unauthorized(e,t){return e.status(401).json({message:t})}}class ge{constructor(e,t){this.log=e,this.model=t}add(){return(e,t)=>te(this,void 0,void 0,(function*(){const r=yield this.model.create(e.body).catch((e=>{me.error(e.message,this.log+".add")}));return r?pe.data(t,{id:r.id}):pe.error(t,"Internal Server Error")}))}all(e,t){return(r,s)=>te(this,void 0,void 0,(function*(){var n,i,d,a,u;e||(e={});const c=Object.assign({},e);c.where=c.where?Object.assign({},c.where):{};const l=null===(n=r.query.limit)||void 0===n?void 0:n.toString();l&&(c.limit=parseInt(l));const m=null===(i=r.query.offset)||void 0===i?void 0:i.toString();m&&(c.offset=parseInt(m));const p=null===(d=r.query.asc)||void 0===d?void 0:d.toString();p&&(c.order=[[p,"ASC"]]);const g=null===(a=r.query.desc)||void 0===a?void 0:a.toString();g&&(c.order=[[g,"DESC"]]);const f=[],h=null===(u=r.query.search)||void 0===u?void 0:u.toString();h&&(Object.keys(this.model.getAttributes()).forEach((e=>{"password"!=e&&f.push({[e]:{[v.like]:`%${h}%`}})})),f.length&&(c.where=Object.assign(Object.assign({},c.where),{[v.or]:[...f]})));const y=yield this.model.findAll(c).catch((e=>{me.error(e.message,this.log+".all")})),w=yield this.model.count(c).catch(o);return y?pe.data(s,{count:w,records:t?t(y):y}):pe.error(s,"Internal Server Error")}))}del(){return(e,t)=>te(this,void 0,void 0,(function*(){const{id:r}=e.params;return(yield this.model.destroy({where:{id:r}}).catch((e=>{me.error(e.message,this.log+".del")})))?pe.success(t,"OK"):pe.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>te(this,void 0,void 0,(function*(){e||(e={});const o=Object.assign({},e);o.where=o.where?Object.assign({},o.where):{};const{id:n}=r.params,i=yield this.model.findByPk(n,o).catch((e=>{me.error(e.message,this.log+".get")}));return i?pe.data(s,t?t(i):i.toJSON()):null===i?pe.notfound(s,"Record not found"):pe.error(s,"Internal Server Error")}))}set(){return(e,t)=>te(this,void 0,void 0,(function*(){const{id:r}=e.params,s=yield this.model.update(e.body,{where:{id:r}}).catch((e=>{me.error(e.message,this.log+".set")}));if(s){const[e]=s;if(e)return pe.success(t,"OK")}return pe.success(t,"Record not changed")}))}}class ve{static all(e,t){return te(this,void 0,void 0,(function*(){return yield de.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:ae,required:!0,include:[{model:ne,required:!0,where:{state:!0},include:[{model:ce,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{me.error(e.message,"permission")}))}))}static get(e){return te(this,void 0,void 0,(function*(){const t=yield ve.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return te(this,void 0,void 0,(function*(){const r=yield ve.all(e,{name:t});return r&&!!r.length}))}}const fe=e=>{if(w(e))return I(e)},he={http:fe(C),token:fe(W)},ye={http:fe(L),token:fe(X)};class we{static sign(e){return ye.token?{token:S(e,ye.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static verify(e){if(!he.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:T(e,he.token)}}catch(e){return{error:"Invalid Token"}}}}const Ie=["id","name","email","username"],be=(e,t,r)=>te(void 0,void 0,void 0,(function*(){const s=e.get(Y)||"",{error:o,decode:n}=we.verify(s);if(o)return pe.error(t,o);if(n){const{id:s,secret:o}=n;if(s&&n){const n=yield ue.findOne({where:{id:s,state:!0}}).catch((e=>{me.error(e.message,"token.check")}));if(n){const s=yield oe.findOne({where:{secret:o,userId:n.id}}).catch((e=>{me.error(e.message,"token.check")}));if(s){const o=Date.now();if(o>s.timestamp)return pe.error(t,"Expired token");s.timestamp=o+6e4*$;const i=e.get("User-Agent");return i&&(s.useragent=i),yield s.save(),e.auth=s,e.user=n,r()}}return pe.error(t,"Access denied")}}return pe.error(t,"Invalid token")})),Se=e=>(t,r,s)=>te(void 0,void 0,void 0,(function*(){const o=t.user;return o?(yield ve.is(o,e))?s():pe.error(r,"Unauthorized access"):pe.unauthorized(r,"Access denied")})),Te=(e,t)=>{const r=a()+"."+t;return w(E(e,r))?Te(e,t):r},Ae=e=>{const t=(null==e?void 0:e.path)||Q,r=O.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>te(void 0,void 0,void 0,(function*(){return s(null,Te(t,A.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||Z),o=O({storage:r,fileFilter(t,r,s){var o;return te(this,void 0,void 0,(function*(){const t=null===(o=null==e?void 0:e.types)||void 0===o?void 0:o.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),n=(null==e?void 0:e.count)||J,i=(null==e?void 0:e.field)||V,d=o.array(i,n);return(e,t,r)=>{d(e,t,(function(e){return e?pe.error(t,e.message):r()}))}},Oe=e=>{const t={abortEarly:!1,allowUnknown:!0,stripUnknown:!0};return(r,s,o)=>{const{error:n,value:i}=e.validate(r.body,t);if(n){const e=n.details.map((e=>e.message)).join(", "),t=[];return n.details.forEach((e=>{var r;t.push({key:(null===(r=e.context)||void 0===r?void 0:r.key)||"",type:e.type})})),pe.validation(s,"Validation error: "+e,t)}return r.body=i,o()}},Ee={username:_.string().min(5).required(),password:_.string().min(5).required()},_e=Oe(_.object(Ee)),Pe=y();Pe.get("/",be,((e,t)=>te(void 0,void 0,void 0,(function*(){const r=e.user;if(!r)return pe.unauthorized(t,"Access denied");const s=yield ve.all(r);if(s){const e=d(Ie,r.toJSON()),o=s.map((e=>e.name));return pe.data(t,Object.assign(Object.assign({},e),{permissions:o}))}return pe.error(t,"Internal Server Error")})))),Pe.post("/login",_e,((e,t)=>te(void 0,void 0,void 0,(function*(){const{username:r,password:s}=e.body;if(!r||!s)return pe.error(t,"Invalid parameters");yield n(q);const o=yield ue.findOne({where:{username:r}}).catch((e=>{me.error(e.message,"auth.login")}));if(!o)return pe.notfound(t,"Username not found");if(!o.state)return pe.error(t,"Username is disabled");const d=b(s).toString();if(o.password!=d)return pe.error(t,"Invalid password");const a=o.id,u=i(),{error:c,token:l}=we.sign({id:a,secret:u});if(c)return pe.error(t,c);if(l){const r=Date.now(),s=r+6e4*$,o=e.get("User-Agent"),n=yield oe.create({login:r,secret:u,timestamp:s,useragent:o,userId:a}).catch((e=>{me.error(e.message,"auth.login")}));if(n)return pe.data(t,{token:l})}return pe.error(t,"Internal Server Error")})))),Pe.get("/logout",be,((e,t)=>te(void 0,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),pe.success(t,"Disconcerted")):pe.unauthorized(t,"Access denied")}))));const Ne=new ge("groups",ne),Re=new ge("groups.route",ae),je=Ne.add(),qe=Ne.all(),ke=Ne.del(),De=Ne.get(),xe=Ne.set(),Be={name:_.string().min(3).required(),description:_.string().allow(null,""),state:_.boolean().required()},ze=Oe(_.object(Be)),Ge={routes:_.array().items(_.number())},Ue=Oe(_.object(Ge)),Ce={name:_.string().min(3).empty(""),description:_.string().allow(null,""),state:_.boolean().empty("")},Le=Oe(_.object(Ce)),He=y();He.use(be),He.get("/",Se("groups.read"),qe),He.post("/",Se("groups.write"),ze,je),He.route("/:id").get(Se("groups.read"),De).put(Se("groups.write"),Le,xe).delete(Se("groups.write"),ke),He.route("/:id/routes").get(Se("groups.read"),Ue,((e,t)=>te(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return Re.all({where:{groupId:r},include:[{model:de,required:!0}]},(e=>e.map((e=>e.route))))(e,t)})))).put(Se("groups.write"),Ue,((e,t)=>te(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,o=yield ne.findByPk(r,{attributes:["id"]}).catch((e=>{me.error(e.message,"groups.routesSet")}));if(o){const e=o.id;if(yield ae.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield de.count({where:{id:s[r]}}),t&&(yield ae.create({groupId:e,routeId:s[r]}))}return pe.success(t,"OK")}return null===o?pe.notfound(t,"Record not found"):pe.error(t,"Internal Server Error")}))));const Ke=new ge("logs",ie),Me=y();Me.use(be),Me.get("/",Se("logs.read"),((e,t)=>te(void 0,void 0,void 0,(function*(){const{source:r,type:s}=e.query,o=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return Ke.all({where:o,order:[["created","DESC"]]})(e,t)}))));const Fe=new ge("route",de),We=Fe.add(),Xe=Fe.all(),Ye=Fe.del(),$e=Fe.get(),Je=Fe.set(),Ve={name:_.string().min(5).required(),description:_.string().allow(null,""),state:_.boolean().required()},Ze=Oe(_.object(Ve)),Qe={name:_.string().min(5).empty(""),description:_.string().allow(null,""),state:_.boolean().empty("")},et=Oe(_.object(Qe)),tt=y();tt.use(be),tt.get("/",Se("routes.read"),Xe),tt.post("/",Se("routes.write"),Ze,We),tt.route("/:id").get(Se("routes.read"),$e).put(Se("routes.write"),et,Je).delete(Se("routes.write"),Ye);const rt=new ge("user",ue),st=new ge("user.groups",ce),ot=["id","name","email","username","description","state"],nt=rt.del(),it={name:_.string().min(5).required(),email:_.string().email().required(),username:_.string().min(5).required(),password:_.string().min(5).required(),description:_.string().allow(null,""),state:_.boolean().required()},dt=Oe(_.object(it)),at={groups:_.array().items(_.number())},ut=Oe(_.object(at)),ct={name:_.string().min(5).empty(""),email:_.string().email().empty(""),username:_.string().min(5).empty(""),password:_.string().min(5).empty(""),description:_.string().allow(null,""),state:_.boolean().empty("")},lt=Oe(_.object(ct)),mt=y();mt.use(be),mt.get("/",Se("users.read"),((e,t)=>te(void 0,void 0,void 0,(function*(){return rt.all({attributes:ot})(e,t)})))),mt.post("/",Se("users.write"),dt,((e,t)=>te(void 0,void 0,void 0,(function*(){return e.body.password=b(e.body.password).toString(),yield rt.add()(e,t)})))),mt.route("/:id").get(Se("users.read"),((e,t)=>te(void 0,void 0,void 0,(function*(){return rt.get({attributes:ot})(e,t)})))).put(Se("users.write"),lt,((e,t)=>te(void 0,void 0,void 0,(function*(){return e.body.password&&(e.body.password=b(e.body.password).toString()),rt.set()(e,t)})))).delete(Se("users.write"),nt),mt.route("/:id/groups").get(Se("users.read"),((e,t)=>te(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return st.all({where:{userId:r},include:[{model:ne,required:!0}]},(e=>e.map((e=>e.group))))(e,t)})))).put(Se("users.write"),ut,((e,t)=>te(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,o=yield ue.findByPk(r,{attributes:["id"]}).catch((e=>{me.error(e.message,"user.groups.set")}));if(o){if(yield ce.destroy({where:{userId:o.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield ne.count({where:{id:s[t]}}),e&&(yield ce.create({userId:o.id,groupId:s[t]}))}return pe.success(t,"OK")}return pe.notfound(t,"Record not found")}))));const pt=y();pt.use("/auth",Pe),pt.use("/groups",He),pt.use("/logs",Me),pt.use("/routes",tt),pt.use("/users",mt);const gt=h();gt.use(h.json()),gt.use(((e,t,r,s)=>e?(me.error(e.message,"express"),pe.error(r,"Internal Server Error")):s())),gt.use(h.urlencoded({extended:!0})),gt.disable("x-powered-by"),M&&gt.use(f());const vt=y();gt.use("/api",vt),gt.use("/api",pt),gt.all("/api/*",((e,t)=>pe.notfound(t,"Invalid API"))),K&&(w(K)&&gt.use(h.static(K)),gt.get("*",((e,t)=>{if(!w(K))return pe.notfound(t,'File "index.html" not found');t.sendFile(K+"/index.html")})));const ft=e=>{const t=new j.Server({server:e,verifyClient:ht});return t.on("connection",(e=>{e.on("message",(t=>te(void 0,void 0,void 0,(function*(){we.verify(t.toString()),e.close()})))),setTimeout((()=>{e.close()}),2e3),e.on("close",(()=>{t.emit("close",e)}))})),t},ht=(e,t)=>t(ee),yt=()=>{se.sync().then((()=>{te(void 0,void 0,void 0,(function*(){if(0==(yield ue.count())){const e={description:"",state:!0},r=yield ue.create(Object.assign({name:"Admin",email:"admin@localhost",username:"admin",password:"8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"},e));if(0==(yield ne.count())){const s=yield ne.create(Object.assign({name:"admin"},e));if(yield ce.create({userId:r.id,groupId:s.id}),0==(yield de.count())){const r=["read","write"],o=["users","groups","permission"];yield t(o,(o=>te(void 0,void 0,void 0,(function*(){yield t(r,(t=>te(void 0,void 0,void 0,(function*(){const r=o+"."+t,n=yield de.create(Object.assign({name:r},e));yield ae.create({groupId:s.id,routeId:n.id})}))))}))));const n=yield de.create(Object.assign({name:"logs.read"},e));yield ae.create({groupId:s.id,routeId:n.id})}}}})),ee&&ft(wt)}))},wt=(e=>{if(!he.http||!ye.http){const t=P.createServer(e);return t.listen(H,(()=>me.info(`Server started on port ${H}`))),t}const t=P.createServer(((e,t)=>{const r=80==H?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),r=N.createServer({key:ye.http,cert:he.http},e);if(F){return new R((e=>{e.once("data",(s=>{e.pause(),e.unshift(s),(22===s[0]?r:t).emit("connection",e),process.nextTick((()=>e.resume()))}))})).listen(H,(()=>me.info(`Server started on port ${H}`))),r}return 443==H&&t.listen(80,(()=>me.info("Server started on port 80"))),r.listen(H,(()=>me.info(`Server started on port ${H}`))),r})(gt);export{q as API_AUTH_SLEEP,k as API_DB_DATABASE,D as API_DB_HOST,U as API_DB_LOG,x as API_DB_PASSWORD,B as API_DB_PORT,z as API_DB_TYPE,G as API_DB_USERNAME,M as API_HTTP_CROSS,C as API_HTTP_CRT,F as API_HTTP_HYBRID,L as API_HTTP_KEY,H as API_HTTP_PORT,K as API_HTTP_PUBLIC,W as API_TOKEN_CRT,Y as API_TOKEN_HEADER,X as API_TOKEN_KEY,$ as API_TOKEN_LIFETIME,J as API_UPLOAD_COUNT,V as API_UPLOAD_FIELD,Z as API_UPLOAD_SIZE,Q as API_UPLOAD_TEMP,ee as API_WEBSOCKET_START,oe as Auth,ge as Controller,ne as Group,ae as GroupRoute,me as Log,ie as Logs,ve as Permission,pe as Responses,de as Route,we as Token,ue as User,ce as UserGroup,gt as app,be as auth,he as crt,yt as initialize,ye as key,Se as permission,vt as router,se as sequelize,wt as server,ft as startSocket,Ae as upload,re as uuid,Oe as validation};
package/dist/index.umd.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * @andrewcaires/api v1.0.2
2
+ * @andrewcaires/api v1.0.3
3
3
  * (c) 2022 Andrew Caires
4
4
  * @license: MIT
5
5
  */
6
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@andrewcaires/utils.js"),t=require("dotenv"),r=require("sequelize"),s=require("cors"),o=require("express"),n=require("fs"),i=require("crypto-js"),a=require("jsonwebtoken"),d=require("joi"),u=require("http"),l=require("https"),c=require("net"),p=require("ws"),f=require("mime-types"),m=require("multer"),g=require("path");function v(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function y(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var h=v(s),I=v(o),T=v(a),w=v(d),_=y(u),A=y(l),P=v(p),S=v(f),b=v(m);t.config();const O=parseInt(process.env.API_AUTH_SLEEP||"1000"),x=process.env.API_DB_DATABASE||"",E=process.env.API_DB_HOST||"127.0.0.1",D=process.env.API_DB_PASSWORD||"",R=parseInt(process.env.API_DB_PORT||"3306"),q=process.env.API_DB_TYPE||"",N=process.env.API_DB_USERNAME||"root",j=e.toBool(process.env.API_DB_LOG||"false"),B=process.env.API_HTTP_CRT||"",k=process.env.API_HTTP_KEY||"",U=parseInt(process.env.API_HTTP_PORT||"3000"),L=process.env.API_HTTP_PUBLIC||"",H=e.toBool(process.env.API_HTTP_CROSS||"false"),z=e.toBool(process.env.API_HTTP_HYBRID||"false"),C=process.env.API_TOKEN_CRT||"",M=process.env.API_TOKEN_KEY||"",G=process.env.API_TOKEN_HEADER||"authorization",K=parseInt(process.env.API_TOKEN_LIFETIME||"15"),F=parseInt(process.env.API_UPLOAD_COUNT||"1"),Y=process.env.API_UPLOAD_FIELD||"upload",W=parseInt(process.env.API_UPLOAD_SIZE||"2"),X=process.env.API_UPLOAD_TEMP||"./temp",$=e.toBool(process.env.API_WEBSOCKET_START||"false");function V(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())}))}const J={type:r.UUID,defaultValue:r.UUIDV4,allowNull:!1,primaryKey:!0},Z=(()=>{switch(q){case"mariadb":return new r.Sequelize(x,N,D,{host:E,port:R,dialect:"mariadb",logging:j,define:{timestamps:!1}});case"mysql":return new r.Sequelize(x,N,D,{host:E,port:R,dialect:"mysql",logging:j,define:{timestamps:!1}});case"postgres":return new r.Sequelize(x,N,D,{host:E,port:R,dialect:"postgres",logging:j,define:{timestamps:!1}})}throw new Error("No database selected")})();class Q extends r.Model{}Q.init({login:r.DataTypes.BIGINT,logout:r.DataTypes.BIGINT,secret:r.DataTypes.STRING,timestamp:r.DataTypes.BIGINT,useragent:r.DataTypes.STRING},{sequelize:Z,modelName:"auth"});class ee extends r.Model{}ee.init({name:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:Z,modelName:"group"});class te extends r.Model{}te.init({type:r.DataTypes.STRING,source:r.DataTypes.STRING,message:r.DataTypes.TEXT},{sequelize:Z,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1});class re extends r.Model{}re.init({name:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:Z,modelName:"route"});class se extends r.Model{}se.init({},{sequelize:Z,modelName:"groups_routes"}),se.removeAttribute("id");class oe extends r.Model{}oe.init({name:r.DataTypes.STRING,email:r.DataTypes.STRING,username:r.DataTypes.STRING,password:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:Z,modelName:"user"});class ne extends r.Model{}ne.init({},{sequelize:Z,modelName:"users_groups"}),ne.removeAttribute("id"),oe.hasMany(Q),Q.belongsTo(oe),ee.hasMany(se),se.belongsTo(ee),re.hasMany(se),se.belongsTo(re),oe.hasMany(ne),ne.belongsTo(oe),ee.hasMany(ne),ne.belongsTo(ee);var ie;!function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(ie||(ie={}));class ae{static write(e,t){ae.writeRaw(ie.NONE,"",e,t)}static error(e,t){ae.writeRaw(ie.ERROR,"error",e,t)}static info(e,t){ae.writeRaw(ie.INFO,"info",e,t)}static success(e,t){ae.writeRaw(ie.ERROR,"success",e,t)}static warning(e,t){ae.writeRaw(ie.WARNING,"warning",e,t)}static writeConsole(t,r,s){const o=e.dateFormat(new Date,"%H:%M:%S");console.log(">",t,r+" ".repeat(10-r.length),"","|",o,"|",s)}static writeRaw(e,t,r,s){ae.writeConsole(e,t,r),te.create({type:t,source:s,message:r}).catch((()=>null))}}class de{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t,r){return e.status(400).json({message:t,details:r})}static unauthorized(e,t){return e.status(401).json({message:t})}}const ue=e=>{if(n.existsSync(e))return n.readFileSync(e)},le={http:ue(B),token:ue(C)},ce={http:ue(k),token:ue(M)};class pe{static all(e,t){return V(this,void 0,void 0,(function*(){return yield re.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:se,required:!0,include:[{model:ee,required:!0,where:{state:!0},include:[{model:ne,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{ae.error(e.message,"permission")}))}))}static get(e){return V(this,void 0,void 0,(function*(){const t=yield pe.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return V(this,void 0,void 0,(function*(){const r=yield pe.all(e,{name:t});return r&&!!r.length}))}}const fe=["id","name","email","username"],me=(e,t,r)=>V(void 0,void 0,void 0,(function*(){const s=e.get(G)||"";if(!le.token)return de.error(t,"Invalid Secret");if(!s||s.split(".").length<3)return de.error(t,"Invalid token");let o;try{o=T.default.verify(s,le.token)}catch(e){return de.error(t,"Invalid token")}if(o&&o.id&&o.secret){const s=yield oe.findOne({where:{id:o.id}}).catch((e=>{ae.error(e.message,"token.check")}));if(s&&s.state){const n=yield Q.findOne({where:{logout:null,secret:o.secret,userId:s.id}}).catch((e=>{ae.error(e.message,"token.check")}));if(n){const o=Date.now();if(o>n.timestamp)return de.error(t,"Expired token");n.timestamp=o+6e4*K;const i=e.get("User-Agent");return i&&(n.useragent=i),yield n.save(),e.auth=n,e.user=s,r()}}return de.error(t,"Access denied")}return de.error(t,"Invalid token")})),ge=e=>{const t={abortEarly:!1,allowUnknown:!0,stripUnknown:!0};return(r,s,o)=>{const{error:n,value:i}=e.validate(r.body,t);if(n){const e=n.details.map((e=>e.message)).join(", "),t=[];return n.details.forEach((e=>{var r;t.push({key:(null===(r=e.context)||void 0===r?void 0:r.key)||"",type:e.type})})),de.validation(s,"Validation error: "+e,t)}return r.body=i,o()}},ve={username:w.default.string().min(5).required(),password:w.default.string().min(5).required()},ye=ge(w.default.object(ve)),he=o.Router();he.get("/",me,((t,r)=>V(void 0,void 0,void 0,(function*(){const s=t.user;if(!s)return de.unauthorized(r,"Access denied");const o=yield pe.all(s);if(o){const t=e.allowedObject(fe,s.toJSON()),n=o.map((e=>e.name));return de.data(r,Object.assign(Object.assign({},t),{permissions:n}))}return de.error(r,"Internal Server Error")})))),he.post("/login",ye,((t,r)=>V(void 0,void 0,void 0,(function*(){const{username:s,password:o}=t.body;if(!s||!o)return de.error(r,"Invalid parameters");yield e.sleep(O);const n=yield oe.findOne({where:{username:s}}).catch((e=>{ae.error(e.message,"auth.login")}));if(!n)return de.notfound(r,"User not found");if(!n.state)return de.error(r,"User is disabled");const a=i.SHA256(o).toString();if(n.password!=a)return de.error(r,"Invalid password");if(!ce.token)return de.error(r,"Invalid Secret");const d=n.id,u=e.uniqueID(),l=T.default.sign({id:d,secret:u},ce.token,{algorithm:"RS256"});if(l){const e=Date.now(),s=e+6e4*K,o=t.get("User-Agent");if(yield Q.create({login:e,secret:u,timestamp:s,useragent:o,userId:d}).catch((e=>{ae.error(e.message,"auth.login")})))return de.data(r,{token:l})}return de.error(r,"Internal Server Error")})))),he.get("/logout",me,((e,t)=>V(void 0,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),de.success(t,"Disconcerted")):de.unauthorized(t,"Access denied")}))));class Ie{constructor(e,t){this.log=e,this.model=t}add(){return(e,t)=>V(this,void 0,void 0,(function*(){const r=yield this.model.create(e.body).catch((e=>{ae.error(e.message,this.log+".add")}));return r?de.data(t,{id:r.id}):de.error(t,"Internal Server Error")}))}all(t,s){return(o,n)=>V(this,void 0,void 0,(function*(){var i,a,d,u,l;t||(t={});const c=Object.assign({},t);c.where=c.where?Object.assign({},c.where):{};const p=null===(i=o.query.limit)||void 0===i?void 0:i.toString();p&&(c.limit=parseInt(p));const f=null===(a=o.query.offset)||void 0===a?void 0:a.toString();f&&(c.offset=parseInt(f));const m=null===(d=o.query.asc)||void 0===d?void 0:d.toString();m&&(c.order=[[m,"ASC"]]);const g=null===(u=o.query.desc)||void 0===u?void 0:u.toString();g&&(c.order=[[g,"DESC"]]);const v=[],y=null===(l=o.query.search)||void 0===l?void 0:l.toString();y&&(Object.keys(this.model.getAttributes()).forEach((e=>{v.push({[e]:{[r.Op.like]:`%${y}%`}})})),v.length&&(c.where=Object.assign(Object.assign({},c.where),{[r.Op.or]:[...v]})));const h=yield this.model.findAll(c).catch((e=>{ae.error(e.message,this.log+".all")})),I=yield this.model.count(c).catch(e.noop);return h?de.data(n,{count:I,records:s?s(h):h}):de.error(n,"Internal Server Error")}))}del(){return(e,t)=>V(this,void 0,void 0,(function*(){const{id:r}=e.params;return(yield this.model.destroy({where:{id:r}}).catch((e=>{ae.error(e.message,this.log+".del")})))?de.success(t,"OK"):de.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>V(this,void 0,void 0,(function*(){e||(e={});const o=Object.assign({},e);o.where=o.where?Object.assign({},o.where):{};const{id:n}=r.params,i=yield this.model.findByPk(n,o).catch((e=>{ae.error(e.message,this.log+".get")}));return i?de.data(s,t?t(i):i.toJSON()):null===i?de.notfound(s,"Record not found"):de.error(s,"Internal Server Error")}))}set(){return(e,t)=>V(this,void 0,void 0,(function*(){const{id:r}=e.params,s=yield this.model.update(e.body,{where:{id:r}}).catch((e=>{ae.error(e.message,this.log+".set")}));if(s){const[e]=s;if(e)return de.success(t,"OK")}return de.success(t,"Record not changed")}))}}const Te=new Ie("groups",ee),we=new Ie("groups.route",se),_e=Te.add(),Ae=Te.all(),Pe=Te.del(),Se=Te.get(),be=Te.set(),Oe=e=>(t,r,s)=>V(void 0,void 0,void 0,(function*(){const o=t.user;return o?(yield pe.is(o,e))?s():de.error(r,"Unauthorized access"):de.unauthorized(r,"Access denied")})),xe={name:w.default.string().min(3).required(),description:w.default.string().allow(null,""),state:w.default.boolean().required()},Ee=ge(w.default.object(xe)),De={routes:w.default.array().items(w.default.number())},Re=ge(w.default.object(De)),qe={name:w.default.string().min(3).empty(""),description:w.default.string().allow(null,""),state:w.default.boolean().empty("")},Ne=ge(w.default.object(qe)),je=o.Router();je.use(me),je.get("/",Oe("groups.read"),Ae),je.post("/",Oe("groups.write"),Ee,_e),je.route("/:id").get(Oe("groups.read"),Se).put(Oe("groups.write"),Ne,be).delete(Oe("groups.write"),Pe),je.route("/:id/routes").get(Oe("groups.read"),Re,((e,t)=>V(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return we.all({where:{groupId:r},include:[{model:re,required:!0}]},(e=>e.map((e=>e.route))))(e,t)})))).put(Oe("groups.write"),Re,((e,t)=>V(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,o=yield ee.findByPk(r,{attributes:["id"]}).catch((e=>{ae.error(e.message,"groups.routesSet")}));if(o){const e=o.id;if(yield se.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield re.count({where:{id:s[r]}}),t&&(yield se.create({groupId:e,routeId:s[r]}))}return de.success(t,"OK")}return null===o?de.notfound(t,"Record not found"):de.error(t,"Internal Server Error")}))));const Be=new Ie("route",re),ke=Be.add(),Ue=Be.all(),Le=Be.del(),He=Be.get(),ze=Be.set(),Ce={name:w.default.string().min(5).required(),description:w.default.string().allow(null,""),state:w.default.boolean().required()},Me=ge(w.default.object(Ce)),Ge={name:w.default.string().min(5).empty(""),description:w.default.string().allow(null,""),state:w.default.boolean().empty("")},Ke=ge(w.default.object(Ge)),Fe=o.Router();Fe.use(me),Fe.get("/",Oe("routes.read"),Ue),Fe.post("/",Oe("routes.write"),Me,ke),Fe.route("/:id").get(Oe("routes.read"),He).put(Oe("routes.write"),Ke,ze).delete(Oe("routes.write"),Le);const Ye=new Ie("user",oe),We=new Ie("user.groups",ne),Xe=["id","name","email","username","description","state"],$e=Ye.del(),Ve={name:w.default.string().min(5).required(),email:w.default.string().email().required(),username:w.default.string().min(5).required(),password:w.default.string().min(5).required(),description:w.default.string().allow(null,""),state:w.default.boolean().required()},Je=ge(w.default.object(Ve)),Ze={groups:w.default.array().items(w.default.number())},Qe=ge(w.default.object(Ze)),et={name:w.default.string().min(5).empty(""),email:w.default.string().email().empty(""),username:w.default.string().min(5).empty(""),password:w.default.string().min(5).empty(""),description:w.default.string().allow(null,""),state:w.default.boolean().empty("")},tt=ge(w.default.object(et)),rt=o.Router();rt.use(me),rt.get("/",Oe("users.read"),((e,t)=>V(void 0,void 0,void 0,(function*(){return Ye.all({attributes:Xe})(e,t)})))),rt.post("/",Oe("users.write"),Je,((e,t)=>V(void 0,void 0,void 0,(function*(){return e.body.password=i.SHA256(e.body.password).toString(),yield Ye.add()(e,t)})))),rt.route("/:id").get(Oe("users.read"),((e,t)=>V(void 0,void 0,void 0,(function*(){return Ye.get({attributes:Xe})(e,t)})))).put(Oe("users.write"),tt,((e,t)=>V(void 0,void 0,void 0,(function*(){return e.body.password&&(e.body.password=i.SHA256(e.body.password).toString()),Ye.set()(e,t)})))).delete(Oe("users.write"),$e),rt.route("/:id/groups").get(Oe("users.read"),((e,t)=>V(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return We.all({where:{userId:r},include:[{model:ee,required:!0}]},(e=>e.map((e=>e.group))))(e,t)})))).put(Oe("users.write"),Qe,((e,t)=>V(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,o=yield oe.findByPk(r,{attributes:["id"]}).catch((e=>{ae.error(e.message,"user.groups.set")}));if(o){if(yield ne.destroy({where:{userId:o.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield ee.count({where:{id:s[t]}}),e&&(yield ne.create({userId:o.id,groupId:s[t]}))}return de.success(t,"OK")}return de.notfound(t,"Record not found")}))));const st=o.Router();st.use("/v1/auth",he),st.use("/v1/groups",je),st.use("/v1/routes",Fe),st.use("/v1/users",rt);const ot=I.default();ot.use(I.default.json()),ot.use(((e,t,r,s)=>e?(ae.error(e.message,"express"),de.error(r,"Internal Server Error")):s())),ot.use(I.default.urlencoded({extended:!0})),ot.disable("x-powered-by"),H&&ot.use(h.default()),ot.use("/api",st),ot.all("/api/*",((e,t)=>de.notfound(t,"Invalid API"))),L&&(n.existsSync(L)&&ot.use(I.default.static(L)),ot.get("*",((e,t)=>{if(!n.existsSync(L))return de.notfound(t,'File "index.html" not found');t.sendFile(L+"/index.html")})));const nt=e=>{const t=new P.default.Server({server:e,verifyClient:it});return t.on("connection",(e=>{e.on("message",(t=>{e.close()})),setTimeout((()=>{e.close()}),2e3),e.on("close",(()=>{t.emit("close",e)}))})),t},it=(e,t)=>t($),at=(e=>{if(!le.http||!ce.http){const t=_.createServer(e);return t.listen(U,(()=>ae.info(`Server started on port ${U}`))),t}const t=_.createServer(((e,t)=>{const r=80==U?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),r=A.createServer({key:ce.http,cert:le.http},e);if(z){return new c.Server((e=>{e.once("data",(s=>{e.pause(),e.unshift(s),(22===s[0]?r:t).emit("connection",e),process.nextTick((()=>e.resume()))}))})).listen(U,(()=>ae.info(`Server started on port ${U}`))),r}return 443==U&&t.listen(80,(()=>ae.info("Server started on port 80"))),r.listen(U,(()=>ae.info(`Server started on port ${U}`))),r})(ot),dt=(t,r)=>{const s=e.uuidv4()+"."+r;return n.existsSync(g.join(t,s))?dt(t,r):s};exports.API_AUTH_SLEEP=O,exports.API_DB_DATABASE=x,exports.API_DB_HOST=E,exports.API_DB_LOG=j,exports.API_DB_PASSWORD=D,exports.API_DB_PORT=R,exports.API_DB_TYPE=q,exports.API_DB_USERNAME=N,exports.API_HTTP_CROSS=H,exports.API_HTTP_CRT=B,exports.API_HTTP_HYBRID=z,exports.API_HTTP_KEY=k,exports.API_HTTP_PORT=U,exports.API_HTTP_PUBLIC=L,exports.API_TOKEN_CRT=C,exports.API_TOKEN_HEADER=G,exports.API_TOKEN_KEY=M,exports.API_TOKEN_LIFETIME=K,exports.API_UPLOAD_COUNT=F,exports.API_UPLOAD_FIELD=Y,exports.API_UPLOAD_SIZE=W,exports.API_UPLOAD_TEMP=X,exports.API_WEBSOCKET_START=$,exports.Auth=Q,exports.Controller=Ie,exports.Group=ee,exports.GroupRoute=se,exports.Log=ae,exports.Logs=te,exports.Permission=pe,exports.Responses=de,exports.Route=re,exports.User=oe,exports.UserGroup=ne,exports.app=ot,exports.auth=me,exports.crt=le,exports.initialize=()=>{Z.sync().then((()=>{V(void 0,void 0,void 0,(function*(){if(0==(yield oe.count())){const t=yield oe.create({name:"Admin",email:"admin@localhost",username:"admin",password:"8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",description:"",state:!0});if(0==(yield ee.count())){const r=yield ee.create({name:"admin",description:"",state:!0});if(yield ne.create({userId:t.id,groupId:r.id}),0==(yield re.count())){const t=["read","write"],s=["users","groups","permission"];e.forEachSeries(s,(s=>V(void 0,void 0,void 0,(function*(){e.forEachSeries(t,(e=>V(void 0,void 0,void 0,(function*(){const t=s.toLowerCase()+"."+e.toLowerCase(),o=yield re.create({name:t,description:"",state:!0});yield se.create({groupId:r.id,routeId:o.id})}))))}))))}}}})),$&&nt(at)}))},exports.key=ce,exports.permission=Oe,exports.router=st,exports.sequelize=Z,exports.server=at,exports.startSocket=nt,exports.upload=e=>{const t=(null==e?void 0:e.path)||X,r=b.default.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>V(void 0,void 0,void 0,(function*(){return s(null,dt(t,S.default.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||W),o=b.default({storage:r,fileFilter(t,r,s){var o;return V(this,void 0,void 0,(function*(){const t=null===(o=null==e?void 0:e.types)||void 0===o?void 0:o.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),n=(null==e?void 0:e.count)||F,i=(null==e?void 0:e.field)||Y,a=o.array(i,n);return(e,t,r)=>{a(e,t,(function(e){return e?de.error(t,e.message):r()}))}},exports.uuid=J,exports.validation=ge;
6
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@andrewcaires/utils.js"),t=require("dotenv"),r=require("sequelize"),s=require("cors"),o=require("express"),n=require("fs"),i=require("crypto-js"),a=require("jsonwebtoken"),d=require("mime-types"),u=require("multer"),l=require("path"),c=require("joi"),p=require("http"),f=require("https"),m=require("net"),g=require("ws");function v(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function y(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var h=v(s),I=v(o),T=v(d),w=v(u),_=v(c),A=y(p),P=y(f),S=v(g);t.config();const b=parseInt(process.env.API_AUTH_SLEEP||"1000"),O=process.env.API_DB_DATABASE||"",x=process.env.API_DB_HOST||"127.0.0.1",E=process.env.API_DB_PASSWORD||"",D=parseInt(process.env.API_DB_PORT||"3306"),R=process.env.API_DB_TYPE||"",q=process.env.API_DB_USERNAME||"root",N=e.toBool(process.env.API_DB_LOG||"false"),j=process.env.API_HTTP_CRT||"",B=process.env.API_HTTP_KEY||"",k=parseInt(process.env.API_HTTP_PORT||"3000"),U=process.env.API_HTTP_PUBLIC||"",H=e.toBool(process.env.API_HTTP_CROSS||"false"),L=e.toBool(process.env.API_HTTP_HYBRID||"false"),z=process.env.API_TOKEN_CRT||"",C=process.env.API_TOKEN_KEY||"",M=process.env.API_TOKEN_HEADER||"authorization",G=parseInt(process.env.API_TOKEN_LIFETIME||"15"),K=parseInt(process.env.API_UPLOAD_COUNT||"1"),F=process.env.API_UPLOAD_FIELD||"upload",Y=parseInt(process.env.API_UPLOAD_SIZE||"2"),W=process.env.API_UPLOAD_TEMP||"./temp",X=e.toBool(process.env.API_WEBSOCKET_START||"false");function $(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())}))}const V={type:r.UUID,defaultValue:r.UUIDV4,allowNull:!1,primaryKey:!0},J=(()=>{switch(R){case"mariadb":return new r.Sequelize(O,q,E,{host:x,port:D,dialect:"mariadb",logging:N,define:{timestamps:!1}});case"mysql":return new r.Sequelize(O,q,E,{host:x,port:D,dialect:"mysql",logging:N,define:{timestamps:!1}});case"postgres":return new r.Sequelize(O,q,E,{host:x,port:D,dialect:"postgres",logging:N,define:{timestamps:!1}})}throw new Error("No database selected")})();class Z extends r.Model{}Z.init({login:r.DataTypes.BIGINT,logout:r.DataTypes.BIGINT,secret:r.DataTypes.STRING,timestamp:r.DataTypes.BIGINT,useragent:r.DataTypes.STRING},{sequelize:J,modelName:"auth"});class Q extends r.Model{}Q.init({name:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:J,modelName:"group"});class ee extends r.Model{}ee.init({type:r.DataTypes.STRING,source:r.DataTypes.STRING,message:r.DataTypes.TEXT},{sequelize:J,modelName:"logs",timestamps:!0,createdAt:"created",updatedAt:!1});class te extends r.Model{}te.init({name:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:J,modelName:"route"});class re extends r.Model{}re.init({},{sequelize:J,modelName:"groups_routes"}),re.removeAttribute("id");class se extends r.Model{}se.init({name:r.DataTypes.STRING,email:r.DataTypes.STRING,username:r.DataTypes.STRING,password:r.DataTypes.STRING,description:r.DataTypes.TEXT,state:r.DataTypes.BOOLEAN},{sequelize:J,modelName:"user"});class oe extends r.Model{}oe.init({},{sequelize:J,modelName:"users_groups"}),oe.removeAttribute("id"),se.hasMany(Z),Z.belongsTo(se),Q.hasMany(re),re.belongsTo(Q),te.hasMany(re),re.belongsTo(te),se.hasMany(oe),oe.belongsTo(se),Q.hasMany(oe),oe.belongsTo(Q);var ne;!function(e){e.ERROR="",e.INFO="",e.NONE="",e.SUCCESS="",e.WARNING=""}(ne||(ne={}));class ie{static write(e,t,r){ie.writeRaw(ne.NONE,"",e,t,r)}static error(e,t,r){ie.writeRaw(ne.ERROR,"error",e,t,r)}static info(e,t,r){ie.writeRaw(ne.INFO,"info",e,t,r)}static success(e,t,r){ie.writeRaw(ne.ERROR,"success",e,t,r)}static warning(e,t,r){ie.writeRaw(ne.WARNING,"warning",e,t,r)}static writeConsole(t,r,s){const o=e.dateFormat(new Date,"%H:%M:%S");console.log(">",t,r+" ".repeat(10-r.length),"","|",o,"|",s)}static writeRaw(t,r,s,o,n){(n=!!e.isUndefined(n)||n)&&ie.writeConsole(t,r,s),ee.create({type:r,source:o,message:s}).catch((()=>null))}}class ae{static success(e,t){return e.status(200).json({message:t})}static data(e,t){return e.status(200).json(Object.assign({},t))}static error(e,t){return e.status(500).json({message:t})}static list(e,t){return e.status(200).json([...t])}static notfound(e,t){return e.status(404).json({message:t})}static validation(e,t,r){return e.status(400).json({message:t,details:r})}static unauthorized(e,t){return e.status(401).json({message:t})}}class de{constructor(e,t){this.log=e,this.model=t}add(){return(e,t)=>$(this,void 0,void 0,(function*(){const r=yield this.model.create(e.body).catch((e=>{ie.error(e.message,this.log+".add")}));return r?ae.data(t,{id:r.id}):ae.error(t,"Internal Server Error")}))}all(t,s){return(o,n)=>$(this,void 0,void 0,(function*(){var i,a,d,u,l;t||(t={});const c=Object.assign({},t);c.where=c.where?Object.assign({},c.where):{};const p=null===(i=o.query.limit)||void 0===i?void 0:i.toString();p&&(c.limit=parseInt(p));const f=null===(a=o.query.offset)||void 0===a?void 0:a.toString();f&&(c.offset=parseInt(f));const m=null===(d=o.query.asc)||void 0===d?void 0:d.toString();m&&(c.order=[[m,"ASC"]]);const g=null===(u=o.query.desc)||void 0===u?void 0:u.toString();g&&(c.order=[[g,"DESC"]]);const v=[],y=null===(l=o.query.search)||void 0===l?void 0:l.toString();y&&(Object.keys(this.model.getAttributes()).forEach((e=>{"password"!=e&&v.push({[e]:{[r.Op.like]:`%${y}%`}})})),v.length&&(c.where=Object.assign(Object.assign({},c.where),{[r.Op.or]:[...v]})));const h=yield this.model.findAll(c).catch((e=>{ie.error(e.message,this.log+".all")})),I=yield this.model.count(c).catch(e.noop);return h?ae.data(n,{count:I,records:s?s(h):h}):ae.error(n,"Internal Server Error")}))}del(){return(e,t)=>$(this,void 0,void 0,(function*(){const{id:r}=e.params;return(yield this.model.destroy({where:{id:r}}).catch((e=>{ie.error(e.message,this.log+".del")})))?ae.success(t,"OK"):ae.notfound(t,"Record not found")}))}get(e,t){return(r,s)=>$(this,void 0,void 0,(function*(){e||(e={});const o=Object.assign({},e);o.where=o.where?Object.assign({},o.where):{};const{id:n}=r.params,i=yield this.model.findByPk(n,o).catch((e=>{ie.error(e.message,this.log+".get")}));return i?ae.data(s,t?t(i):i.toJSON()):null===i?ae.notfound(s,"Record not found"):ae.error(s,"Internal Server Error")}))}set(){return(e,t)=>$(this,void 0,void 0,(function*(){const{id:r}=e.params,s=yield this.model.update(e.body,{where:{id:r}}).catch((e=>{ie.error(e.message,this.log+".set")}));if(s){const[e]=s;if(e)return ae.success(t,"OK")}return ae.success(t,"Record not changed")}))}}class ue{static all(e,t){return $(this,void 0,void 0,(function*(){return yield te.findAll({where:Object.assign(Object.assign({},t),{state:!0}),include:[{model:re,required:!0,include:[{model:Q,required:!0,where:{state:!0},include:[{model:oe,required:!0,where:{userId:e.id}}]}]}]}).catch((e=>{ie.error(e.message,"permission")}))}))}static get(e){return $(this,void 0,void 0,(function*(){const t=yield ue.all(e);return t?t.map((e=>e.name)):[]}))}static is(e,t){return $(this,void 0,void 0,(function*(){const r=yield ue.all(e,{name:t});return r&&!!r.length}))}}const le=e=>{if(n.existsSync(e))return n.readFileSync(e)},ce={http:le(j),token:le(z)},pe={http:le(B),token:le(C)};class fe{static sign(e){return pe.token?{token:a.sign(e,pe.token,{algorithm:"RS256"})}:{error:"Invalid Secret"}}static verify(e){if(!ce.token)return{error:"Invalid Secret"};if(!e||e.split(".").length<3)return{error:"Invalid Token"};try{return{decode:a.verify(e,ce.token)}}catch(e){return{error:"Invalid Token"}}}}const me=["id","name","email","username"],ge=(e,t,r)=>$(void 0,void 0,void 0,(function*(){const s=e.get(M)||"",{error:o,decode:n}=fe.verify(s);if(o)return ae.error(t,o);if(n){const{id:s,secret:o}=n;if(s&&n){const n=yield se.findOne({where:{id:s,state:!0}}).catch((e=>{ie.error(e.message,"token.check")}));if(n){const s=yield Z.findOne({where:{secret:o,userId:n.id}}).catch((e=>{ie.error(e.message,"token.check")}));if(s){const o=Date.now();if(o>s.timestamp)return ae.error(t,"Expired token");s.timestamp=o+6e4*G;const i=e.get("User-Agent");return i&&(s.useragent=i),yield s.save(),e.auth=s,e.user=n,r()}}return ae.error(t,"Access denied")}}return ae.error(t,"Invalid token")})),ve=e=>(t,r,s)=>$(void 0,void 0,void 0,(function*(){const o=t.user;return o?(yield ue.is(o,e))?s():ae.error(r,"Unauthorized access"):ae.unauthorized(r,"Access denied")})),ye=(t,r)=>{const s=e.uuidv4()+"."+r;return n.existsSync(l.join(t,s))?ye(t,r):s},he=e=>{const t={abortEarly:!1,allowUnknown:!0,stripUnknown:!0};return(r,s,o)=>{const{error:n,value:i}=e.validate(r.body,t);if(n){const e=n.details.map((e=>e.message)).join(", "),t=[];return n.details.forEach((e=>{var r;t.push({key:(null===(r=e.context)||void 0===r?void 0:r.key)||"",type:e.type})})),ae.validation(s,"Validation error: "+e,t)}return r.body=i,o()}},Ie={username:_.default.string().min(5).required(),password:_.default.string().min(5).required()},Te=he(_.default.object(Ie)),we=o.Router();we.get("/",ge,((t,r)=>$(void 0,void 0,void 0,(function*(){const s=t.user;if(!s)return ae.unauthorized(r,"Access denied");const o=yield ue.all(s);if(o){const t=e.allowedObject(me,s.toJSON()),n=o.map((e=>e.name));return ae.data(r,Object.assign(Object.assign({},t),{permissions:n}))}return ae.error(r,"Internal Server Error")})))),we.post("/login",Te,((t,r)=>$(void 0,void 0,void 0,(function*(){const{username:s,password:o}=t.body;if(!s||!o)return ae.error(r,"Invalid parameters");yield e.sleep(b);const n=yield se.findOne({where:{username:s}}).catch((e=>{ie.error(e.message,"auth.login")}));if(!n)return ae.notfound(r,"Username not found");if(!n.state)return ae.error(r,"Username is disabled");const a=i.SHA256(o).toString();if(n.password!=a)return ae.error(r,"Invalid password");const d=n.id,u=e.uniqueID(),{error:l,token:c}=fe.sign({id:d,secret:u});if(l)return ae.error(r,l);if(c){const e=Date.now(),s=e+6e4*G,o=t.get("User-Agent"),n=yield Z.create({login:e,secret:u,timestamp:s,useragent:o,userId:d}).catch((e=>{ie.error(e.message,"auth.login")}));if(n)return ae.data(r,{token:c})}return ae.error(r,"Internal Server Error")})))),we.get("/logout",ge,((e,t)=>$(void 0,void 0,void 0,(function*(){const r=e.auth;return r?(r.logout=Date.now(),r.timestamp=r.logout,yield r.save(),ae.success(t,"Disconcerted")):ae.unauthorized(t,"Access denied")}))));const _e=new de("groups",Q),Ae=new de("groups.route",re),Pe=_e.add(),Se=_e.all(),be=_e.del(),Oe=_e.get(),xe=_e.set(),Ee={name:_.default.string().min(3).required(),description:_.default.string().allow(null,""),state:_.default.boolean().required()},De=he(_.default.object(Ee)),Re={routes:_.default.array().items(_.default.number())},qe=he(_.default.object(Re)),Ne={name:_.default.string().min(3).empty(""),description:_.default.string().allow(null,""),state:_.default.boolean().empty("")},je=he(_.default.object(Ne)),Be=o.Router();Be.use(ge),Be.get("/",ve("groups.read"),Se),Be.post("/",ve("groups.write"),De,Pe),Be.route("/:id").get(ve("groups.read"),Oe).put(ve("groups.write"),je,xe).delete(ve("groups.write"),be),Be.route("/:id/routes").get(ve("groups.read"),qe,((e,t)=>$(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return Ae.all({where:{groupId:r},include:[{model:te,required:!0}]},(e=>e.map((e=>e.route))))(e,t)})))).put(ve("groups.write"),qe,((e,t)=>$(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{routes:s}=e.body,o=yield Q.findByPk(r,{attributes:["id"]}).catch((e=>{ie.error(e.message,"groups.routesSet")}));if(o){const e=o.id;if(yield re.destroy({where:{groupId:e}}),s){let t=0;for(let r=0;r<s.length;r++)t=yield te.count({where:{id:s[r]}}),t&&(yield re.create({groupId:e,routeId:s[r]}))}return ae.success(t,"OK")}return null===o?ae.notfound(t,"Record not found"):ae.error(t,"Internal Server Error")}))));const ke=new de("logs",ee),Ue=o.Router();Ue.use(ge),Ue.get("/",ve("logs.read"),((e,t)=>$(void 0,void 0,void 0,(function*(){const{source:r,type:s}=e.query,o=r&&s?{source:r,type:s}:r?{source:r}:s?{type:s}:{};return ke.all({where:o,order:[["created","DESC"]]})(e,t)}))));const He=new de("route",te),Le=He.add(),ze=He.all(),Ce=He.del(),Me=He.get(),Ge=He.set(),Ke={name:_.default.string().min(5).required(),description:_.default.string().allow(null,""),state:_.default.boolean().required()},Fe=he(_.default.object(Ke)),Ye={name:_.default.string().min(5).empty(""),description:_.default.string().allow(null,""),state:_.default.boolean().empty("")},We=he(_.default.object(Ye)),Xe=o.Router();Xe.use(ge),Xe.get("/",ve("routes.read"),ze),Xe.post("/",ve("routes.write"),Fe,Le),Xe.route("/:id").get(ve("routes.read"),Me).put(ve("routes.write"),We,Ge).delete(ve("routes.write"),Ce);const $e=new de("user",se),Ve=new de("user.groups",oe),Je=["id","name","email","username","description","state"],Ze=$e.del(),Qe={name:_.default.string().min(5).required(),email:_.default.string().email().required(),username:_.default.string().min(5).required(),password:_.default.string().min(5).required(),description:_.default.string().allow(null,""),state:_.default.boolean().required()},et=he(_.default.object(Qe)),tt={groups:_.default.array().items(_.default.number())},rt=he(_.default.object(tt)),st={name:_.default.string().min(5).empty(""),email:_.default.string().email().empty(""),username:_.default.string().min(5).empty(""),password:_.default.string().min(5).empty(""),description:_.default.string().allow(null,""),state:_.default.boolean().empty("")},ot=he(_.default.object(st)),nt=o.Router();nt.use(ge),nt.get("/",ve("users.read"),((e,t)=>$(void 0,void 0,void 0,(function*(){return $e.all({attributes:Je})(e,t)})))),nt.post("/",ve("users.write"),et,((e,t)=>$(void 0,void 0,void 0,(function*(){return e.body.password=i.SHA256(e.body.password).toString(),yield $e.add()(e,t)})))),nt.route("/:id").get(ve("users.read"),((e,t)=>$(void 0,void 0,void 0,(function*(){return $e.get({attributes:Je})(e,t)})))).put(ve("users.write"),ot,((e,t)=>$(void 0,void 0,void 0,(function*(){return e.body.password&&(e.body.password=i.SHA256(e.body.password).toString()),$e.set()(e,t)})))).delete(ve("users.write"),Ze),nt.route("/:id/groups").get(ve("users.read"),((e,t)=>$(void 0,void 0,void 0,(function*(){const{id:r}=e.params;return Ve.all({where:{userId:r},include:[{model:Q,required:!0}]},(e=>e.map((e=>e.group))))(e,t)})))).put(ve("users.write"),rt,((e,t)=>$(void 0,void 0,void 0,(function*(){const{id:r}=e.params,{groups:s}=e.body,o=yield se.findByPk(r,{attributes:["id"]}).catch((e=>{ie.error(e.message,"user.groups.set")}));if(o){if(yield oe.destroy({where:{userId:o.id}}),s){let e=0;for(let t=0;t<s.length;t++)e=yield Q.count({where:{id:s[t]}}),e&&(yield oe.create({userId:o.id,groupId:s[t]}))}return ae.success(t,"OK")}return ae.notfound(t,"Record not found")}))));const it=o.Router();it.use("/auth",we),it.use("/groups",Be),it.use("/logs",Ue),it.use("/routes",Xe),it.use("/users",nt);const at=I.default();at.use(I.default.json()),at.use(((e,t,r,s)=>e?(ie.error(e.message,"express"),ae.error(r,"Internal Server Error")):s())),at.use(I.default.urlencoded({extended:!0})),at.disable("x-powered-by"),H&&at.use(h.default());const dt=o.Router();at.use("/api",dt),at.use("/api",it),at.all("/api/*",((e,t)=>ae.notfound(t,"Invalid API"))),U&&(n.existsSync(U)&&at.use(I.default.static(U)),at.get("*",((e,t)=>{if(!n.existsSync(U))return ae.notfound(t,'File "index.html" not found');t.sendFile(U+"/index.html")})));const ut=e=>{const t=new S.default.Server({server:e,verifyClient:lt});return t.on("connection",(e=>{e.on("message",(t=>$(void 0,void 0,void 0,(function*(){fe.verify(t.toString()),e.close()})))),setTimeout((()=>{e.close()}),2e3),e.on("close",(()=>{t.emit("close",e)}))})),t},lt=(e,t)=>t(X),ct=(e=>{if(!ce.http||!pe.http){const t=A.createServer(e);return t.listen(k,(()=>ie.info(`Server started on port ${k}`))),t}const t=A.createServer(((e,t)=>{const r=80==k?":80":"";t.writeHead(301,{Location:"https://"+e.headers.host+r+e.url}),t.end()})),r=P.createServer({key:pe.http,cert:ce.http},e);if(L){return new m.Server((e=>{e.once("data",(s=>{e.pause(),e.unshift(s),(22===s[0]?r:t).emit("connection",e),process.nextTick((()=>e.resume()))}))})).listen(k,(()=>ie.info(`Server started on port ${k}`))),r}return 443==k&&t.listen(80,(()=>ie.info("Server started on port 80"))),r.listen(k,(()=>ie.info(`Server started on port ${k}`))),r})(at);exports.API_AUTH_SLEEP=b,exports.API_DB_DATABASE=O,exports.API_DB_HOST=x,exports.API_DB_LOG=N,exports.API_DB_PASSWORD=E,exports.API_DB_PORT=D,exports.API_DB_TYPE=R,exports.API_DB_USERNAME=q,exports.API_HTTP_CROSS=H,exports.API_HTTP_CRT=j,exports.API_HTTP_HYBRID=L,exports.API_HTTP_KEY=B,exports.API_HTTP_PORT=k,exports.API_HTTP_PUBLIC=U,exports.API_TOKEN_CRT=z,exports.API_TOKEN_HEADER=M,exports.API_TOKEN_KEY=C,exports.API_TOKEN_LIFETIME=G,exports.API_UPLOAD_COUNT=K,exports.API_UPLOAD_FIELD=F,exports.API_UPLOAD_SIZE=Y,exports.API_UPLOAD_TEMP=W,exports.API_WEBSOCKET_START=X,exports.Auth=Z,exports.Controller=de,exports.Group=Q,exports.GroupRoute=re,exports.Log=ie,exports.Logs=ee,exports.Permission=ue,exports.Responses=ae,exports.Route=te,exports.Token=fe,exports.User=se,exports.UserGroup=oe,exports.app=at,exports.auth=ge,exports.crt=ce,exports.initialize=()=>{J.sync().then((()=>{$(void 0,void 0,void 0,(function*(){if(0==(yield se.count())){const t={description:"",state:!0},r=yield se.create(Object.assign({name:"Admin",email:"admin@localhost",username:"admin",password:"8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"},t));if(0==(yield Q.count())){const s=yield Q.create(Object.assign({name:"admin"},t));if(yield oe.create({userId:r.id,groupId:s.id}),0==(yield te.count())){const r=["read","write"],o=["users","groups","permission"];yield e.forEachSeries(o,(o=>$(void 0,void 0,void 0,(function*(){yield e.forEachSeries(r,(e=>$(void 0,void 0,void 0,(function*(){const r=o+"."+e,n=yield te.create(Object.assign({name:r},t));yield re.create({groupId:s.id,routeId:n.id})}))))}))));const n=yield te.create(Object.assign({name:"logs.read"},t));yield re.create({groupId:s.id,routeId:n.id})}}}})),X&&ut(ct)}))},exports.key=pe,exports.permission=ve,exports.router=dt,exports.sequelize=J,exports.server=ct,exports.startSocket=ut,exports.upload=e=>{const t=(null==e?void 0:e.path)||W,r=w.default.diskStorage({destination:(e,r,s)=>s(null,t),filename:(e,r,s)=>$(void 0,void 0,void 0,(function*(){return s(null,ye(t,T.default.extension(r.mimetype)||"bin"))}))}),s=1e6*((null==e?void 0:e.size)||Y),o=w.default({storage:r,fileFilter(t,r,s){var o;return $(this,void 0,void 0,(function*(){const t=null===(o=null==e?void 0:e.types)||void 0===o?void 0:o.indexOf(r.mimetype);return void 0!==t&&t<0?s(new Error("File type not allowed")):s(null,!0)}))},limits:{fileSize:s}}),n=(null==e?void 0:e.count)||K,i=(null==e?void 0:e.field)||F,a=o.array(i,n);return(e,t,r)=>{a(e,t,(function(e){return e?ae.error(t,e.message):r()}))}},exports.uuid=V,exports.validation=he;
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@andrewcaires/api",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Simple api for small applications using express, jsonwebtoken, sequelize and websocket",
5
5
  "main": "dist/index.umd.js",
6
6
  "module": "dist/index.esm.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
9
  "serve": "ts-node src/test.ts",
10
- "build": "rollup -c build/rollup.config.js"
10
+ "build": "rollup -c build/rollup.config.js",
11
+ "dev": "ts-node-dev --respawn --transpile-only ./src/index.ts"
11
12
  },
12
13
  "repository": {
13
14
  "type": "git",
@@ -34,7 +35,7 @@
34
35
  },
35
36
  "homepage": "https://github.com/andrewcaires/npm/tree/main/api#readme",
36
37
  "dependencies": {
37
- "@andrewcaires/utils.js": "^0.1.0",
38
+ "@andrewcaires/utils.js": "^0.1.5",
38
39
  "cors": "^2.8.5",
39
40
  "crypto-js": "^4.1.1",
40
41
  "dotenv": "^16.0.1",
@@ -44,30 +45,32 @@
44
45
  "jsonwebtoken": "^8.5.1",
45
46
  "mariadb": "^3.0.0",
46
47
  "mime-types": "^2.1.35",
47
- "multer": "^1.4.4",
48
+ "multer": "^1.4.5-lts.1",
48
49
  "mysql2": "^2.3.3",
49
50
  "pg": "^8.7.3",
50
51
  "pg-hstore": "^2.3.4",
51
- "sequelize": "^6.19.1",
52
- "ws": "^8.6.0"
52
+ "sequelize": "^6.21.2",
53
+ "ws": "^8.8.0"
53
54
  },
54
55
  "devDependencies": {
55
- "@rollup/plugin-typescript": "^8.3.2",
56
+ "@rollup/plugin-commonjs": "^22.0.1",
57
+ "@rollup/plugin-typescript": "^8.3.3",
56
58
  "@types/cors": "^2.8.12",
57
59
  "@types/crypto-js": "^4.1.1",
58
60
  "@types/express": "^4.17.13",
59
61
  "@types/jsonwebtoken": "^8.5.8",
60
62
  "@types/mime-types": "^2.1.1",
61
63
  "@types/multer": "^1.4.7",
62
- "@types/node": "^17.0.34",
64
+ "@types/node": "^18.0.1",
63
65
  "@types/ws": "^8.5.3",
64
- "@typescript-eslint/eslint-plugin": "^5.24.0",
65
- "@typescript-eslint/parser": "^5.24.0",
66
- "eslint": "^8.15.0",
67
- "rollup": "^2.73.0",
68
- "rollup-plugin-dts": "^4.2.1",
66
+ "@typescript-eslint/eslint-plugin": "^5.30.4",
67
+ "@typescript-eslint/parser": "^5.30.0",
68
+ "eslint": "^8.19.0",
69
+ "rollup": "^2.75.7",
70
+ "rollup-plugin-dts": "^4.2.2",
69
71
  "rollup-plugin-terser": "^7.0.2",
70
- "ts-node": "^10.7.0",
71
- "typescript": "^4.6.4"
72
+ "ts-node": "^10.8.2",
73
+ "ts-node-dev": "^2.0.0",
74
+ "typescript": "^4.7.4"
72
75
  }
73
76
  }