├── .dockerignore ├── .gitattributes ├── .gitignore ├── Dockerfile ├── README.md ├── app.ts ├── bootstrap.ts ├── config ├── .env.dev └── .env.prod ├── lib ├── app.js ├── app.js.map ├── bootstrap.js ├── bootstrap.js.map ├── src │ ├── db │ │ ├── mongoConfig.js │ │ ├── mongoConfig.js.map │ │ ├── mongoose.js │ │ ├── mongoose.js.map │ │ └── schemas │ │ │ ├── UserSchema.js │ │ │ └── UserSchema.js.map │ ├── entities │ │ ├── User.js │ │ └── User.js.map │ ├── handlers │ │ ├── UserHandler.js │ │ └── UserHandler.js.map │ ├── middlewares │ │ └── plugins │ │ │ ├── HapiSwaggerPlugin.js │ │ │ └── HapiSwaggerPlugin.js.map │ ├── routes │ │ ├── UserRoute.js │ │ ├── UserRoute.js.map │ │ └── interfaces │ │ │ ├── IRoute.js │ │ │ └── IRoute.js.map │ └── services │ │ ├── UserService.js │ │ ├── UserService.js.map │ │ ├── base │ │ ├── Base.js │ │ └── Base.js.map │ │ └── interfaces │ │ ├── IBase.js │ │ └── IBase.js.map └── tests │ ├── UserRouterTest.js │ └── UserRouterTest.js.map ├── package-lock.json ├── package.json ├── src ├── db │ ├── mongoConfig.ts │ ├── mongoose.ts │ └── schemas │ │ └── UserSchema.ts ├── entities │ └── User.ts ├── handlers │ └── UserHandler.ts ├── middlewares │ └── plugins │ │ └── HapiSwaggerPlugin.ts ├── routes │ ├── UserRoute.ts │ ├── base │ │ └── BaseRoute.ts │ └── interfaces │ │ └── IRoute.ts └── services │ ├── UserService.ts │ ├── base │ └── Base.ts │ └── interfaces │ └── IBase.ts ├── tests └── UserRouterTest.ts ├── tsconfig.json └── tslint.json /.dockerignore: -------------------------------------------------------------------------------- 1 | GIT_KEY 2 | .git 3 | .gitatributes 4 | node_modules 5 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | .env.* filter=git-crypt diff=git-crypt 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | 3 | 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | # IDE files 12 | .idea 13 | 14 | package-lock.json 15 | 16 | # Logs 17 | logs 18 | *.log 19 | 20 | # Runtime data 21 | pids 22 | *.pid 23 | *.seed 24 | *.pid.lock 25 | 26 | # Directory for instrumented libs generated by jscoverage/JSCover 27 | lib-cov 28 | 29 | # Coverage directory used by tools like istanbul 30 | coverage 31 | 32 | # nyc test coverage 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 36 | .grunt 37 | 38 | # Bower dependency directory (https://bower.io/) 39 | bower_components 40 | 41 | # node-waf configuration 42 | .lock-wscript 43 | 44 | # Compiled binary addons (http://nodejs.org/api/addons.html) 45 | build/Release 46 | 47 | # Dependency directories 48 | node_modules/ 49 | jspm_packages/ 50 | 51 | # Typescript v1 declaration files 52 | typings/ 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Optional REPL history 61 | .node_repl_history 62 | 63 | # Output of 'npm pack' 64 | *.tgz 65 | 66 | # Yarn Integrity file 67 | .yarn-integrity 68 | 69 | # dotenv environment variables file 70 | .env 71 | 72 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 73 | .grunt 74 | 75 | # Compiled binary addons (http://nodejs.org/api/addons.html) 76 | build/Release 77 | 78 | # Dependency directory 79 | # Commenting this out is preferred by some people, see 80 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 81 | node_modules 82 | 83 | # Users Environment Variables 84 | .lock-wscript 85 | 86 | # Runtime configuration for swagger app 87 | config/runtime.yaml 88 | GIT_KEY 89 | /config/certificates 90 | .git-crypt 91 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8.7.0 2 | ADD . /app 3 | WORKDIR /app 4 | RUN npm i -g yarn 5 | RUN npm i -g pm2 6 | RUN yarn install 7 | RUN pm2 start /lib/bootstrap.js 8 | EXPOSE 8080 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Horizon Four - OneCode - TS - RESTFUL API com TypeScript e JWT Auth 2 | 3 |

4 | 5 |

6 | Este é o repositório da base de uma API Rest com Hapi.js, Moongoose, JWTAuth e TypeScript, para utilizarmos como base para projetos futuros. 7 | **Dúvidas ?** erick.wendel@horizonfour.com.br 8 | 9 | ### Status (CICD) 10 | 11 | | Branch | Status | 12 | | ------ | ------ | 13 | | master | ? | 14 | | develop | ? | 15 | 16 | ### Pull Request 17 | Todos os projetos precisam passar code review de pelo menos um membro do time H4. 18 | 19 | ### Importante! 20 | **Para construção desse template de API foi utilizado o Git-Crypt, para verificar seu uso, acesse** 21 | [GitCrypt Tutorial](https://medium.com/trainingcenter/protegendo-dados-sens%C3%ADveis-com-git-crypt-9fca13e6835b). 22 | **E para acessar esse ambiente entre em contato e solicite a chave** :smile: 23 | 24 | 25 | ### Principais Dependencias 26 | Esta é a lista com as principais dependencias que o seu projeto deve possuir. 27 | 28 | | Tipo | Nome | Link | 29 | | ------ | ------ | ------ | 30 | | Tests/Framework | Mocha | [Mocha](https://mochajs.org) | 31 | | Tests/Runner | ? | - | 32 | | Transpiler | Typescript | [TS](www.typescriptlang.org) | 33 | | CICD | ? | [SemaphoreCI](https://www.semaphoreci.com) | 34 | | Server | Microsoft Azure (GCP) | [Azure]() | 35 | 36 | ### Ferramentas 37 | Para que você possa iniciar o desenvolvimento, verifique se você possui todas as ferramentas abaixo com o setup correto em sua máquina. 38 | 39 | | Ferramenta | Link | 40 | | ------ | ------ | 41 | | Docker | [Link](https://www.docker.com/) | 42 | | GitFlow | [Link](https://github.com/nvie/gitflow/wiki/Installation) | 43 | | GitCrypt | [Link](https://github.com/AGWA/git-crypt) | 44 | | TSLint | [Link](https://palantir.github.io/tslint/) | 45 | | Airbnb Styleguide | [Link](https://github.com/airbnb/javascript) | 46 | | Prettier | [Link](https://github.com/prettier/prettier) | 47 | | JSDoc | [Link](http://usejsdoc.org) | 48 | | JIRA | [Link](https://horizonfour.atlassian.net/) | 49 | 50 | 51 | #### Caso cliente externo que não possua Typescript no projeto 52 | | Ferramenta | Link | 53 | | ------ | ------ | 54 | | ESLint | [Link](https://eslint.org) | 55 | 56 | 57 | ### Dica 58 | - Adicione as regras de `Linters` (eslint ou tslint) descritas no projeto, no `formatOnSave` do seu editor. 59 | - Adicione adicione também o prettier e configure no `formatOnSave` para organizar e formatar o seu codigo. 60 | 61 | ## IMPORTANTE 62 | Nós utilizamos um pipe de CI/CD via [SemaphoreCI.](https://semaphoreci.com/) 63 | 64 | O processo de test + build + deploy é realizado de maneira automática pelo CI escolhido. Todo commit no repositório do GitHub é deployado automáticamente, por isso muita atenção na `branch master`. 65 | 66 | **Isso aí. Tudo pronto pra construírmos um projeto DO CARALHO! #GOH4** 67 | 68 | ## Créditos 69 | - Este repositório foi baseado na documentação do [Drafteam](github.com/drafteam) 70 | -------------------------------------------------------------------------------- /app.ts: -------------------------------------------------------------------------------- 1 | import * as Hapi from 'hapi'; 2 | import { BaseRoute } from './src/routes/base/BaseRoute'; 3 | const inert = require('inert'); // Usado para exposição de arquivos estáticos. 4 | const vision = require('vision'); // Usado para administração de template engines 5 | const hapiJwt = require('hapi-auth-jwt2'); 6 | const hapiSwagger = require('hapi-swagger'); 7 | 8 | const validate = (decoded: any, request: any, callback: any) => { 9 | if (decoded) return callback(null, true); 10 | return callback(null, false); 11 | }; 12 | 13 | async function startApi(): Promise { 14 | try { 15 | // Instancia o HapiJS 16 | const server = new Hapi.Server(); 17 | await server.connection({ port: process.env.PORT || 3000 }); 18 | 19 | // register plugins 20 | await server.register([ 21 | inert, 22 | vision, 23 | { 24 | register: hapiSwagger, 25 | options: { 26 | info: { title: 'Nome do Projeto', version: '0.1' }, 27 | }, 28 | }, 29 | hapiJwt, 30 | ]); 31 | 32 | // Autenticação JWT 33 | await server.auth.strategy('jwt', 'jwt', { 34 | key: process.env.JWT_SECRET, 35 | validateFunc: validate, 36 | verifyOptions: { algorithms: ['HS256'] }, 37 | }); 38 | 39 | await server.route(BaseRoute.routes()); 40 | 41 | await server.start(); 42 | 43 | const uri = server.info ? server.info.uri : 0; 44 | console.info(`SERVIDOR EXECUTANDO: ${uri}`); 45 | return server; 46 | } catch (error) { 47 | console.error(`Falha na inicialização da API: ${error}`); 48 | return new Hapi.Server(); 49 | } 50 | } 51 | 52 | export default startApi; 53 | -------------------------------------------------------------------------------- /bootstrap.ts: -------------------------------------------------------------------------------- 1 | // Set .env variables using DOTENV package 2 | import * as dotenv from 'dotenv'; 3 | 4 | if (process.env.ENVIRONMENT !== 'PROD') { 5 | dotenv.config({ path: './config/.env.dev' }); 6 | } else { 7 | dotenv.config({ path: './config/.env.prod' }); 8 | } 9 | 10 | import * as app from './app.js'; 11 | export default app.default(); 12 | -------------------------------------------------------------------------------- /config/.env.dev: -------------------------------------------------------------------------------- 1 | ENVIRONMENT=DEV 2 | BCRYPT_SALT="$2a$06$LnEFKTTejWv3UyS4fb5DjO" 3 | APP_PORT=8080 4 | JWT_SECRET=HorizonFour 5 | 6 | DB_MONGO_HOST=localhost 7 | DB_MONGO_PORT=27017 8 | DB_MONGO_DATABASE=onecode 9 | -------------------------------------------------------------------------------- /config/.env.prod: -------------------------------------------------------------------------------- 1 | ENVIRONMENT=PROD 2 | BCRYPT_SALT="$2a$06$LnEFKTTejWv3UyS4fb5DjO" 3 | APP_PORT=8080 4 | SEQUELIZE_DIALECT=mysql 5 | SEQUELIZE_FREEZE_TABLE=true 6 | SEQUELIZE_UNDERSCORED=true -------------------------------------------------------------------------------- /lib/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const Hapi = require("hapi"); 4 | const BaseRoute_1 = require("./src/routes/base/BaseRoute"); 5 | const inert = require('inert'); // Usado para exposição de arquivos estáticos. 6 | const vision = require('vision'); // Usado para administração de template engines 7 | const hapiJwt = require('hapi-auth-jwt2'); 8 | const hapiSwagger = require('hapi-swagger'); 9 | const validate = (decoded, request, callback) => { 10 | if (decoded) 11 | return callback(null, true); 12 | return callback(null, false); 13 | }; 14 | async function startApi() { 15 | try { 16 | // Instancia o HapiJS 17 | const server = new Hapi.Server(); 18 | await server.connection({ port: process.env.PORT || 3000 }); 19 | // register plugins 20 | await server.register([ 21 | inert, 22 | vision, 23 | { 24 | register: hapiSwagger, 25 | options: { 26 | info: { title: 'Nome do Projeto', version: '0.1' }, 27 | }, 28 | }, 29 | hapiJwt, 30 | ]); 31 | // Autenticação JWT 32 | await server.auth.strategy('jwt', 'jwt', { 33 | key: process.env.JWT_SECRET, 34 | validateFunc: validate, 35 | verifyOptions: { algorithms: ['HS256'] }, 36 | }); 37 | await server.route(BaseRoute_1.BaseRoute.routes()); 38 | await server.start(); 39 | const uri = server.info ? server.info.uri : 0; 40 | console.info(`SERVIDOR EXECUTANDO: ${uri}`); 41 | return server; 42 | } 43 | catch (error) { 44 | console.error(`Falha na inicialização da API: ${error}`); 45 | return new Hapi.Server(); 46 | } 47 | } 48 | exports.default = startApi; 49 | //# sourceMappingURL=app.js.map -------------------------------------------------------------------------------- /lib/app.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"app.js","sourceRoot":"","sources":["../app.ts"],"names":[],"mappings":";;AAAA,6BAA6B;AAC7B,2DAAwD;AACxD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,8CAA8C;AAC9E,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,+CAA+C;AACjF,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AAE5C,MAAM,QAAQ,GAAG,CAAC,OAAY,EAAE,OAAY,EAAE,QAAa,EAAE,EAAE;IAC7D,EAAE,CAAC,CAAC,OAAO,CAAC;QAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC/B,CAAC,CAAC;AAEF,KAAK;IACH,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;QAE5D,mBAAmB;QACnB,MAAM,MAAM,CAAC,QAAQ,CAAC;YACpB,KAAK;YACL,MAAM;YACN;gBACE,QAAQ,EAAE,WAAW;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE;iBACnD;aACF;YACD,OAAO;SACR,CAAC,CAAC;QAEH,mBAAmB;QACnB,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE;YACvC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;YAC3B,YAAY,EAAE,QAAQ;YACtB,aAAa,EAAE,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE;SACzC,CAAC,CAAC;QAEH,MAAM,MAAM,CAAC,KAAK,CAAC,qBAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAEvC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAErB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC;IAChB,CAAC;IAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,kBAAe,QAAQ,CAAC"} -------------------------------------------------------------------------------- /lib/bootstrap.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | // Set .env variables using DOTENV package 4 | const dotenv = require("dotenv"); 5 | if (process.env.ENVIRONMENT !== 'PROD') { 6 | dotenv.config({ path: './config/.env.dev' }); 7 | } 8 | else { 9 | dotenv.config({ path: './config/.env.prod' }); 10 | } 11 | const app = require("./app.js"); 12 | exports.default = app.default(); 13 | //# sourceMappingURL=bootstrap.js.map -------------------------------------------------------------------------------- /lib/bootstrap.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../bootstrap.ts"],"names":[],"mappings":";;AAAA,0CAA0C;AAC1C,iCAAiC;AAEjC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;AAC/C,CAAC;AAAC,IAAI,CAAC,CAAC;IACN,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,gCAAgC;AAChC,kBAAe,GAAG,CAAC,OAAO,EAAE,CAAC"} -------------------------------------------------------------------------------- /lib/src/db/mongoConfig.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const HOST = process.env.DB_MONGO_HOST || 'localhost'; 4 | const PORT = process.env.DB_MONGO_PORT || '27017'; 5 | const DATABASE = process.env.DB_MONGO_DATABASE || 'onecode'; 6 | const URI = `mongodb://${HOST}:${PORT}/${DATABASE}`; 7 | exports.default = { 8 | options: { 9 | useMongoClient: true, 10 | }, 11 | connection: URI, 12 | }; 13 | //# sourceMappingURL=mongoConfig.js.map -------------------------------------------------------------------------------- /lib/src/db/mongoConfig.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"mongoConfig.js","sourceRoot":"","sources":["../../../src/db/mongoConfig.ts"],"names":[],"mappings":";;AAAA,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,WAAW,CAAC;AACtD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC;AAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,SAAS,CAAC;AAE5D,MAAM,GAAG,GAAG,aAAa,IAAI,IAAI,IAAI,IAAI,QAAQ,EAAE,CAAC;AAEpD,kBAAe;IACb,OAAO,EAAE;QACP,cAAc,EAAE,IAAI;KACrB;IACD,UAAU,EAAE,GAAG;CAChB,CAAC"} -------------------------------------------------------------------------------- /lib/src/db/mongoose.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const mongoConfig_1 = require("./mongoConfig"); 4 | const Mongoose = require("mongoose"); 5 | const mongoose = require('mongoose'); 6 | // tslint:disable-next-line:ter-arrow-parens 7 | Mongoose.connect(mongoConfig_1.default.connection, err => { 8 | if (err) 9 | console.log('Erro ao conectar com a base de dados: ' + err); 10 | }); 11 | mongoose.Promise = global.Promise; 12 | exports.default = Mongoose; 13 | //# sourceMappingURL=mongoose.js.map -------------------------------------------------------------------------------- /lib/src/db/mongoose.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"mongoose.js","sourceRoot":"","sources":["../../../src/db/mongoose.ts"],"names":[],"mappings":";;AAAA,+CAAwC;AACxC,qCAAqC;AAErC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAErC,4CAA4C;AAC5C,QAAQ,CAAC,OAAO,CAAC,qBAAW,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE;IAC7C,EAAE,CAAC,CAAC,GAAG,CAAC;QAAC,OAAO,CAAC,GAAG,CAAC,wCAAwC,GAAG,GAAG,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;AAElC,kBAAe,QAAQ,CAAC"} -------------------------------------------------------------------------------- /lib/src/db/schemas/UserSchema.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const mongoose_1 = require("./../mongoose"); 4 | /** 5 | * Schema usuários no banco. 6 | */ 7 | const userSchema = new mongoose_1.default.Schema({ 8 | name: { 9 | required: true, 10 | type: String, 11 | unique: true, 12 | }, 13 | password: { 14 | required: true, 15 | type: String, 16 | }, 17 | }); 18 | exports.default = mongoose_1.default.model('User', userSchema); 19 | //# sourceMappingURL=UserSchema.js.map -------------------------------------------------------------------------------- /lib/src/db/schemas/UserSchema.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"UserSchema.js","sourceRoot":"","sources":["../../../../src/db/schemas/UserSchema.ts"],"names":[],"mappings":";;AAAA,4CAAqC;AACrC;;GAEG;AAEH,MAAM,UAAU,GAAG,IAAI,kBAAQ,CAAC,MAAM,CAAC;IACrC,IAAI,EAAE;QACJ,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACR,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,MAAM;KACb;CACF,CAAC,CAAC;AAEH,kBAAe,kBAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC"} -------------------------------------------------------------------------------- /lib/src/entities/User.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | class User { 4 | } 5 | exports.User = User; 6 | //# sourceMappingURL=User.js.map -------------------------------------------------------------------------------- /lib/src/entities/User.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"User.js","sourceRoot":"","sources":["../../../src/entities/User.ts"],"names":[],"mappings":";;AAAA;CAIC;AAJD,oBAIC"} -------------------------------------------------------------------------------- /lib/src/handlers/UserHandler.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const UserService_1 = require("../services/UserService"); 4 | class UserHandler { 5 | constructor() { 6 | this.query = { 7 | skip: 0, 8 | limit: 100, 9 | order: { 10 | field: '', 11 | order: '', 12 | }, 13 | }; 14 | this._userService = new UserService_1.UserService(); 15 | } 16 | async list(request, reply) { 17 | try { 18 | const query = request.payload; 19 | const user = await this._userService.list(query, this.query); 20 | return reply(user); 21 | } 22 | catch (e) { 23 | console.log(e); 24 | return reply(e.message).code(500); 25 | } 26 | } 27 | async findOne(request, reply) { 28 | try { 29 | const { id } = request.params; 30 | const user = await this._userService.findOne({ _id: id }); 31 | return reply(user); 32 | } 33 | catch (e) { 34 | console.log(e); 35 | return reply(e.message).code(500); 36 | } 37 | } 38 | async create(request, reply) { 39 | try { 40 | const user = request.payload; 41 | const newUser = await this._userService.create(user); 42 | return reply(newUser); 43 | } 44 | catch (e) { 45 | console.log(e); 46 | return reply(e.message).code(500); 47 | } 48 | } 49 | async update(request, reply) { 50 | try { 51 | const { id } = request.params; 52 | const item = request.payload; 53 | const updatedUser = await this._userService.update({ _id: id }, item); 54 | return reply(updatedUser); 55 | } 56 | catch (e) { 57 | console.log(e); 58 | return reply(e.message).code(500); 59 | } 60 | } 61 | async signIn(request, reply) { 62 | try { 63 | const user = request.payload; 64 | const updatedUser = await this._userService.signIn(user); 65 | return reply(updatedUser); 66 | } 67 | catch (e) { 68 | console.log(e); 69 | return reply(e.message).code(500); 70 | } 71 | } 72 | async remove(request, reply) { 73 | try { 74 | const { id } = request.params; 75 | const user = await this._userService.remove(id); 76 | return reply(user); 77 | } 78 | catch (e) { 79 | console.log(e); 80 | return reply(e.message).code(500); 81 | } 82 | } 83 | } 84 | exports.UserHandler = UserHandler; 85 | //# sourceMappingURL=UserHandler.js.map -------------------------------------------------------------------------------- /lib/src/handlers/UserHandler.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"UserHandler.js","sourceRoot":"","sources":["../../../src/handlers/UserHandler.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /lib/src/middlewares/plugins/HapiSwaggerPlugin.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const inert = require('inert'); 4 | const vision = require('vision'); 5 | const hapiSwagger = require('hapi-swagger'); 6 | class Swagger { 7 | static info() { 8 | return { 9 | name: 'Swagger Documentation', 10 | version: '1.0.0', 11 | }; 12 | } 13 | static register(server) { 14 | server.register([ 15 | inert, 16 | vision, 17 | { 18 | register: hapiSwagger, 19 | options: { 20 | info: { 21 | title: 'Product Store Documentation', 22 | version: '1.0', 23 | }, 24 | securityDefinitions: { 25 | jwt: { 26 | type: 'apiKey', 27 | name: 'Authorization', 28 | in: 'header', 29 | }, 30 | }, 31 | security: [{ jwt: [] }], 32 | }, 33 | }, 34 | ]); 35 | } 36 | } 37 | exports.default = Swagger; 38 | Object.seal(Swagger); 39 | //# sourceMappingURL=HapiSwaggerPlugin.js.map -------------------------------------------------------------------------------- /lib/src/middlewares/plugins/HapiSwaggerPlugin.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"HapiSwaggerPlugin.js","sourceRoot":"","sources":["../../../../src/middlewares/plugins/HapiSwaggerPlugin.ts"],"names":[],"mappings":";;AACA,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AACjC,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AAE5C;IACE,MAAM,CAAC,IAAI;QACT,MAAM,CAAC;YACL,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,OAAO;SACjB,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,MAAmB;QACjC,MAAM,CAAC,QAAQ,CAAC;YACd,KAAK;YACL,MAAM;YACN;gBACE,QAAQ,EAAE,WAAW;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE;wBACJ,KAAK,EAAE,6BAA6B;wBACpC,OAAO,EAAE,KAAK;qBACf;oBACD,mBAAmB,EAAE;wBACnB,GAAG,EAAE;4BACH,IAAI,EAAE,QAAQ;4BACd,IAAI,EAAE,eAAe;4BACrB,EAAE,EAAE,QAAQ;yBACb;qBACF;oBACD,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;iBACxB;aACF;SACF,CAAC,CAAC;IACL,CAAC;CACF;AA/BD,0BA+BC;AACD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC"} -------------------------------------------------------------------------------- /lib/src/routes/UserRoute.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const UserHandler_1 = require("./../handlers/UserHandler"); 4 | const Joi = require("joi"); 5 | class UserRoute { 6 | constructor() { 7 | this.userHandler = new UserHandler_1.UserHandler(); 8 | } 9 | /** 10 | * Retorna a configuração para a rota POST /user 11 | * @returns Hapi.RouteConfiguration 12 | */ 13 | login() { 14 | return { 15 | path: '/users/login', 16 | method: 'POST', 17 | config: { 18 | handler: async (request, reply) => { 19 | return await this.userHandler.signIn(request, reply); 20 | }, 21 | auth: false, 22 | description: 'Ativa a sessão de um usuário', 23 | notes: 'Ativa a sessão de um usuário, para futuramente devolver um token de acesso.', 24 | tags: ['api'], 25 | validate: { 26 | payload: { 27 | name: Joi.string().required(), 28 | password: Joi.string().required(), 29 | }, 30 | }, 31 | }, 32 | }; 33 | } 34 | /* 35 | * @returns [Returns the Route object for HapiRouter to setup] 36 | * @memberOf HelloWorldRoute 37 | */ 38 | list() { 39 | return { 40 | path: '/users', 41 | method: 'GET', 42 | config: { 43 | handler: async (request, reply) => { 44 | return await this.userHandler.list(request, reply); 45 | }, 46 | auth: 'jwt', 47 | description: 'Lista todos os usuários', 48 | notes: 'Lista todos os usuário registrados, Coordenadores ou não', 49 | tags: ['api'], 50 | validate: { 51 | headers: Joi.object({ 52 | authorization: Joi.string().required(), 53 | }).unknown(), 54 | }, 55 | }, 56 | }; 57 | } 58 | /* 59 | * @returns [Returns the Route object for HapiRouter to setup] 60 | * @memberOf HelloWorldRoute 61 | */ 62 | findOne() { 63 | return { 64 | path: '/users/{id}', 65 | method: 'GET', 66 | config: { 67 | handler: async (request, reply) => { 68 | return await this.userHandler.findOne(request, reply); 69 | }, 70 | auth: 'jwt', 71 | description: 'Obtem um usuário', 72 | notes: 'Obtem um usuário', 73 | tags: ['api'], 74 | validate: { 75 | params: { 76 | id: Joi.string().required(), 77 | }, 78 | headers: Joi.object({ 79 | authorization: Joi.string().required(), 80 | }).unknown(), 81 | }, 82 | }, 83 | }; 84 | } 85 | /** 86 | * [Retorna a configuração da rota DELETE.] 87 | * @returns [Hapi.RouteConfiguration] 88 | * @memberOf RegionRoute 89 | */ 90 | remove() { 91 | return { 92 | path: '/users/{id}', 93 | method: 'DELETE', 94 | handler: async (request, reply) => { 95 | return await this.userHandler.remove(request, reply); 96 | }, 97 | config: { 98 | auth: 'jwt', 99 | description: 'Remove um usuário', 100 | notes: 'Remove um usuário', 101 | tags: ['api'], 102 | validate: { 103 | headers: Joi.object({ 104 | authorization: Joi.string().required(), 105 | }).unknown(), 106 | params: { 107 | id: Joi.string().required(), 108 | }, 109 | }, 110 | }, 111 | }; 112 | } 113 | /** 114 | * [Retorna a configuração da rota DELETE.] 115 | * @returns [Hapi.RouteConfiguration] 116 | * @memberOf RegionRoute 117 | */ 118 | update() { 119 | return { 120 | path: '/users/{id}', 121 | method: 'PUT', 122 | handler: async (request, reply) => { 123 | return await this.userHandler.update(request, reply); 124 | }, 125 | config: { 126 | auth: 'jwt', 127 | description: 'Altera um usuário', 128 | notes: 'Altera um usuário', 129 | tags: ['api'], 130 | validate: { 131 | headers: Joi.object({ 132 | authorization: Joi.string().required(), 133 | }).unknown(), 134 | payload: { 135 | name: Joi.string(), 136 | password: Joi.string(), 137 | }, 138 | params: { 139 | id: Joi.string().required(), 140 | }, 141 | }, 142 | }, 143 | }; 144 | } 145 | /** 146 | * [Retorna a configuração da rota POST.] 147 | * @returns [Hapi.RouteConfiguration] 148 | * @memberOf RegionRoute 149 | */ 150 | create() { 151 | return { 152 | path: '/users', 153 | method: 'POST', 154 | handler: async (request, reply) => { 155 | return await this.userHandler.create(request, reply); 156 | }, 157 | config: { 158 | auth: 'jwt', 159 | description: 'Realiza o cadastro de usuário', 160 | notes: 'Cria um usuário, gerando a hash da senha dele.', 161 | tags: ['api'], 162 | validate: { 163 | payload: { 164 | name: Joi.string().required(), 165 | password: Joi.string() 166 | .required() 167 | .min(6) 168 | .max(12), 169 | }, 170 | headers: Joi.object({ 171 | authorization: Joi.string().required(), 172 | }).unknown(), 173 | }, 174 | }, 175 | }; 176 | } 177 | /** 178 | * Retorna um array com todas as configurações de rotas desse objeto. 179 | * @returns Hapi.RouteConfiguration[] 180 | */ 181 | routes() { 182 | return [ 183 | this.login(), 184 | this.list(), 185 | this.findOne(), 186 | this.remove(), 187 | this.update(), 188 | this.create(), 189 | ]; 190 | } 191 | } 192 | exports.UserRoute = UserRoute; 193 | //# sourceMappingURL=UserRoute.js.map -------------------------------------------------------------------------------- /lib/src/routes/UserRoute.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"UserRoute.js","sourceRoot":"","sources":["../../../src/routes/UserRoute.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /lib/src/routes/interfaces/IRoute.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=IRoute.js.map -------------------------------------------------------------------------------- /lib/src/routes/interfaces/IRoute.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"IRoute.js","sourceRoot":"","sources":["../../../../src/routes/interfaces/IRoute.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /lib/src/services/UserService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const bcrypt = require("bcrypt"); 4 | const Base_1 = require("./base/Base"); 5 | const UserSchema_1 = require("../db/schemas/UserSchema"); 6 | // const JWT = require('jsonwebtoken'); 7 | const Jwt = require("jsonwebtoken"); 8 | class UserService extends Base_1.default { 9 | constructor() { 10 | super(UserSchema_1.default); 11 | } 12 | generateHash(password) { 13 | return bcrypt.hash(password, 10); 14 | } 15 | async validateHash(user, hash) { 16 | return await bcrypt.compare(user.password, hash); 17 | } 18 | async signIn(user) { 19 | const { name } = user; 20 | const userDb = (await this.findOne({ name })); 21 | if (!userDb) { 22 | throw new Error('Usuário não encontrado'); 23 | } 24 | const validHash = await this.validateHash(user, userDb.password); 25 | if (!validHash) 26 | throw new Error('Usuário ou senha incorretos'); 27 | return Jwt.sign(user, process.env.JWT_SECRET || ''); 28 | } 29 | async create(user) { 30 | user.password = await this.generateHash(user.password); 31 | const existentUser = await this.findOne({ name: user.name }); 32 | if (existentUser) 33 | throw new Error('Usuário existente!'); 34 | const created = await super.create(user); 35 | if (created) { 36 | return { 37 | status: true, 38 | _id: created.id, 39 | }; 40 | } 41 | return { 42 | status: false, 43 | }; 44 | } 45 | } 46 | exports.UserService = UserService; 47 | //# sourceMappingURL=UserService.js.map -------------------------------------------------------------------------------- /lib/src/services/UserService.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"UserService.js","sourceRoot":"","sources":["../../../src/services/UserService.ts"],"names":[],"mappings":";;AAAA,iCAAiC;AACjC,sCAA+B;AAE/B,yDAAkD;AAClD,uCAAuC;AACvC,oCAAoC;AAEpC,iBAAyB,SAAQ,cAAU;IACzC;QACE,KAAK,CAAC,oBAAU,CAAC,CAAC;IACpB,CAAC;IAED,YAAY,CAAC,QAAgB;QAC3B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAU,EAAE,IAAY;QACzC,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAU;QACrB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QACtB,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAS,CAAC;QACtD,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YAAC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAE/D,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAU;QACrB,IAAI,CAAC,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,EAAE,CAAC,CAAC,YAAY,CAAC;YAAC,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAExD,MAAM,OAAO,GAAQ,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE9C,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC;gBACL,MAAM,EAAE,IAAI;gBACZ,GAAG,EAAE,OAAO,CAAC,EAAE;aAChB,CAAC;QACJ,CAAC;QAED,MAAM,CAAC;YACL,MAAM,EAAE,KAAK;SACd,CAAC;IACJ,CAAC;CACF;AA7CD,kCA6CC"} -------------------------------------------------------------------------------- /lib/src/services/base/Base.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | class Base { 4 | constructor(database) { 5 | this._database = database; 6 | } 7 | async create(item) { 8 | const result = await this._database.create(item); 9 | return { status: 'created', id: result._id.toString() }; 10 | } 11 | async update(fields, item, upsert = false) { 12 | const result = await this._database.update(fields, { upsert, $set: item }); 13 | return result; 14 | } 15 | async findOne(query, lean = true) { 16 | const result = (await this._database.findOne(query).lean(lean)); 17 | return result; 18 | } 19 | async list(query = {}, options) { 20 | const result = await this._database.find(query, { __v: 0 }, options); 21 | return result; 22 | } 23 | async find(query, item) { 24 | const result = await this._database.find(item, {}, item); 25 | return result; 26 | } 27 | async remove(id) { 28 | const result = await this._database.remove({ _id: id }); 29 | return { status: result }; 30 | } 31 | } 32 | exports.default = Base; 33 | //# sourceMappingURL=Base.js.map -------------------------------------------------------------------------------- /lib/src/services/base/Base.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Base.js","sourceRoot":"","sources":["../../../../src/services/base/Base.ts"],"names":[],"mappings":";;AAGA;IAIE,YAAY,QAAa;QACvB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,IAAO;QAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,MAAM,CACV,MAAc,EACd,IAAO,EACP,SAAkB,KAAK;QAEvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,MAAM,CAAC,MAAM,CAAC;IAChB,CAAC;IACD,KAAK,CAAC,OAAO,CACX,KAAa,EACb,OAAgB,IAAI;QAEpB,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAM,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,QAAgB,EAAE,EAClB,OAIC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,KAAa,EACb,IAIC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF;AACD,kBAAe,IAAI,CAAC"} -------------------------------------------------------------------------------- /lib/src/services/interfaces/IBase.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=IBase.js.map -------------------------------------------------------------------------------- /lib/src/services/interfaces/IBase.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"IBase.js","sourceRoot":"","sources":["../../../../src/services/interfaces/IBase.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /lib/tests/UserRouterTest.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const ava_1 = require("ava"); 4 | const request = require('hapi-test-request'); 5 | const app_1 = require("./../app"); 6 | const UserService_1 = require("../src/services/UserService"); 7 | const dotenv = require("dotenv"); 8 | if (process.env.ENVIRONMENT !== 'PROD') { 9 | dotenv.config({ path: './config/.env.dev' }); 10 | } 11 | else { 12 | dotenv.config({ path: './config/.env.prod' }); 13 | } 14 | let server; 15 | let id; 16 | const service = new UserService_1.UserService(); 17 | const MOCK_USER = { 18 | id: undefined, 19 | name: `teste4@test.com`, 20 | password: '1234565', 21 | }; 22 | const MOCK_INSERT = { 23 | name: `${new Date().getTime()}teste4@test.com`, 24 | password: '123123', 25 | }; 26 | const MOCKED_TOKEN = 27 | // tslint:disable-next-line:max-line-length 28 | 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiRXJpY2sgV2VuZGVsIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJpYXQiOjE1MTEyMjA2ODl9.CaofBWm56rjM7Pe11-OHCJu0PvK7AJZ2AkZbRFTQ7mk'; 29 | ava_1.test.before(async () => { 30 | const item = await app_1.default(); 31 | server = request(item); 32 | }); 33 | ava_1.test.before(async () => { 34 | let result = await service.findOne({ name: MOCK_USER.name }); 35 | if (result) { 36 | id = result._id; 37 | return; 38 | } 39 | result = await service.create(MOCK_USER); 40 | id = result.id; 41 | }); 42 | ava_1.test('GET /users/login - deve realizar login e obter token', async (t) => { 43 | const req = { 44 | method: 'POST', 45 | url: '/users/login', 46 | payload: JSON.stringify({ 47 | name: MOCK_USER.name, 48 | password: MOCK_USER.password, 49 | }), 50 | }; 51 | const res = await server.call(req); 52 | t.true(res.result.length >= 160); 53 | }); 54 | ava_1.test('GET /users - listar usuarios', async (t) => { 55 | const req = { 56 | method: 'GET', 57 | url: '/users', 58 | headers: { 59 | Authorization: `${MOCKED_TOKEN}`, 60 | }, 61 | }; 62 | const result = await server.call(req); 63 | const payload = JSON.parse(result.payload); 64 | t.true(payload.length >= 0); 65 | }); 66 | ava_1.test('GET /users/{id} - obter um usuario', async (t) => { 67 | const req = { 68 | method: 'GET', 69 | url: `/users/${id}`, 70 | headers: { 71 | Authorization: `${MOCKED_TOKEN}`, 72 | }, 73 | }; 74 | const result = await server.call(req); 75 | const { name } = JSON.parse(result.payload); 76 | t.deepEqual(name, MOCK_USER.name); 77 | }); 78 | ava_1.test('POST /users - cadastrar usuario', async (t) => { 79 | const req = { 80 | method: 'POST', 81 | url: '/users', 82 | headers: { 83 | Authorization: `${MOCKED_TOKEN}`, 84 | }, 85 | payload: MOCK_INSERT, 86 | }; 87 | const result = await server.call(req); 88 | const payload = JSON.parse(result.payload); 89 | t.true(payload.status); 90 | }); 91 | ava_1.test('PUT /users/${id} - Atualizar usuario', async (t) => { 92 | const user = await service.create({ 93 | name: 'Test2' + new Date().getTime(), 94 | password: '123456', 95 | }); 96 | const req = { 97 | method: 'PUT', 98 | url: `/users/${user._id}`, 99 | headers: { 100 | Authorization: `${MOCKED_TOKEN}`, 101 | }, 102 | payload: { 103 | name: `${new Date().getTime()}updated@test.com`, 104 | }, 105 | }; 106 | const result = await server.call(req); 107 | const payload = JSON.parse(result.payload); 108 | t.true(payload.ok === 1); 109 | }); 110 | ava_1.test.after('DELETE /users/${id} - Remover usuarios', async (t) => { 111 | const user = await service.create({ 112 | name: 'Test2' + new Date().getTime(), 113 | password: '123456', 114 | }); 115 | const req = { 116 | method: 'DELETE', 117 | url: `/users/${user._id}`, 118 | headers: { 119 | Authorization: `${MOCKED_TOKEN}`, 120 | }, 121 | }; 122 | const res = await server.call(req); 123 | t.true(res.result.status.result.ok === 1); 124 | }); 125 | // test.after('Remove mocked data from db', async (t: TestContext) => { 126 | // const item: any = await service.findOne({ name: MOCK_INSERT.name }); 127 | // await service.remove(item._id); 128 | // }); 129 | //# sourceMappingURL=UserRouterTest.js.map -------------------------------------------------------------------------------- /lib/tests/UserRouterTest.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"UserRouterTest.js","sourceRoot":"","sources":["../../tests/UserRouterTest.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "one-code", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "bootstrap.ts", 6 | "scripts": { 7 | "build": "tsc", 8 | "start": "nodemon lib/bootstrap.js", 9 | "test": "ava lib/tests" 10 | }, 11 | "author": "Horizon Four", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@types/bcrypt": "1.0.0", 15 | "@types/dotenv": "4.0.1", 16 | "@types/hapi": "16.1.10", 17 | "@types/joi": "10.4.3", 18 | "@types/jsonwebtoken": "^7.2.3", 19 | "@types/mocha": "2.2.43", 20 | "@types/mongoose": "4.7.23", 21 | "@types/node": "8.0.51", 22 | "@types/vision": "4.1.2", 23 | "bcrypt": "1.0.3", 24 | "boom": "6.0.0", 25 | "dotenv": "4.0.0", 26 | "hapi": "16.6.2", 27 | "hapi-auth-jwt2": "7.3.0", 28 | "hapi-handlers": "2.0.0", 29 | "hapi-router": "3.5.0", 30 | "hapi-swagger": "7.8.1", 31 | "inert": "4.2.1", 32 | "joi": "13.0.0", 33 | "joi-objectid": "2.0.0", 34 | "jsonwebtoken": "^8.1.0", 35 | "mongoose": "4.12.3", 36 | "tslint-config-airbnb": "5.3.0", 37 | "typescript": "2.5.3", 38 | "vision": "4.1.1" 39 | }, 40 | "devDependencies": { 41 | "ava": "0.22.0", 42 | "hapi-test-request": "0.0.4", 43 | "mocha": "4.0.1", 44 | "nodemon": "1.12.1" 45 | }, 46 | "ava": { 47 | "files": ["lib/tests/*"], 48 | "source": ["**/**.{js,ts}"] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/db/mongoConfig.ts: -------------------------------------------------------------------------------- 1 | const HOST = process.env.DB_MONGO_HOST || 'localhost'; 2 | const PORT = process.env.DB_MONGO_PORT || '27017'; 3 | const DATABASE = process.env.DB_MONGO_DATABASE || 'onecode'; 4 | 5 | const URI = `mongodb://${HOST}:${PORT}/${DATABASE}`; 6 | 7 | export default { 8 | options: { 9 | useMongoClient: true, 10 | }, 11 | connection: URI, 12 | }; 13 | -------------------------------------------------------------------------------- /src/db/mongoose.ts: -------------------------------------------------------------------------------- 1 | import mongoConfig from './mongoConfig'; 2 | import * as Mongoose from 'mongoose'; 3 | 4 | const mongoose = require('mongoose'); 5 | 6 | // tslint:disable-next-line:ter-arrow-parens 7 | Mongoose.connect(mongoConfig.connection, err => { 8 | if (err) console.log('Erro ao conectar com a base de dados: ' + err); 9 | }); 10 | 11 | mongoose.Promise = global.Promise; 12 | 13 | export default Mongoose; 14 | -------------------------------------------------------------------------------- /src/db/schemas/UserSchema.ts: -------------------------------------------------------------------------------- 1 | import mongoose from './../mongoose'; 2 | /** 3 | * Schema usuários no banco. 4 | */ 5 | 6 | const userSchema = new mongoose.Schema({ 7 | name: { 8 | required: true, 9 | type: String, 10 | unique: true, 11 | }, 12 | password: { 13 | required: true, 14 | type: String, 15 | }, 16 | }); 17 | 18 | export default mongoose.model('User', userSchema); 19 | -------------------------------------------------------------------------------- /src/entities/User.ts: -------------------------------------------------------------------------------- 1 | export class User { 2 | public id: string | undefined; 3 | public name: string; 4 | public password: string; 5 | } 6 | -------------------------------------------------------------------------------- /src/handlers/UserHandler.ts: -------------------------------------------------------------------------------- 1 | import * as Hapi from 'hapi'; 2 | import * as mongoose from 'mongoose'; 3 | import * as jwt from 'jsonwebtoken'; 4 | import * as Boom from 'boom'; 5 | import { UserService } from '../services/UserService'; 6 | import { User } from '../entities/User'; 7 | 8 | export class UserHandler { 9 | // tslint:disable-next-line:variable-name 10 | private _userService: UserService; 11 | private query = { 12 | skip: 0, 13 | limit: 100, 14 | order: { 15 | field: '', 16 | order: '', 17 | }, 18 | }; 19 | 20 | constructor() { 21 | this._userService = new UserService(); 22 | } 23 | 24 | public async list( 25 | request: Hapi.Request, 26 | reply: Hapi.ReplyNoContinue, 27 | ): Promise { 28 | try { 29 | const query = request.payload; 30 | const user = await this._userService.list(query, this.query); 31 | return reply(user); 32 | } catch (e) { 33 | console.log(e); 34 | return reply(e.message).code(500); 35 | } 36 | } 37 | 38 | public async findOne( 39 | request: Hapi.Request, 40 | reply: Hapi.ReplyNoContinue, 41 | ): Promise { 42 | try { 43 | const { id } = request.params; 44 | const user = await this._userService.findOne({ _id: id }); 45 | return reply(user); 46 | } catch (e) { 47 | console.log(e); 48 | return reply(e.message).code(500); 49 | } 50 | } 51 | public async create( 52 | request: Hapi.Request, 53 | reply: Hapi.ReplyNoContinue, 54 | ): Promise { 55 | try { 56 | const user = request.payload; 57 | const newUser = await this._userService.create(user); 58 | return reply(newUser); 59 | } catch (e) { 60 | console.log(e); 61 | return reply(e.message).code(500); 62 | } 63 | } 64 | 65 | public async update( 66 | request: Hapi.Request, 67 | reply: Hapi.ReplyNoContinue, 68 | ): Promise { 69 | try { 70 | const { id } = request.params; 71 | const item = request.payload; 72 | const updatedUser = await this._userService.update({ _id: id }, item); 73 | return reply(updatedUser); 74 | } catch (e) { 75 | console.log(e); 76 | return reply(e.message).code(500); 77 | } 78 | } 79 | 80 | public async signIn( 81 | request: Hapi.Request, 82 | reply: Hapi.ReplyNoContinue, 83 | ): Promise { 84 | try { 85 | const user = request.payload; 86 | const updatedUser = await this._userService.signIn(user); 87 | return reply(updatedUser); 88 | } catch (e) { 89 | console.log(e); 90 | return reply(e.message).code(500); 91 | } 92 | } 93 | 94 | public async remove( 95 | request: Hapi.Request, 96 | reply: Hapi.ReplyNoContinue, 97 | ): Promise { 98 | try { 99 | const { id } = request.params; 100 | const user = await this._userService.remove(id); 101 | return reply(user); 102 | } catch (e) { 103 | console.log(e); 104 | return reply(e.message).code(500); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/middlewares/plugins/HapiSwaggerPlugin.ts: -------------------------------------------------------------------------------- 1 | import * as Hapi from 'hapi'; 2 | const inert = require('inert'); 3 | const vision = require('vision'); 4 | const hapiSwagger = require('hapi-swagger'); 5 | 6 | export default class Swagger { 7 | static info() { 8 | return { 9 | name: 'Swagger Documentation', 10 | version: '1.0.0', 11 | }; 12 | } 13 | 14 | static register(server: Hapi.Server) { 15 | server.register([ 16 | inert, 17 | vision, 18 | { 19 | register: hapiSwagger, 20 | options: { 21 | info: { 22 | title: 'Product Store Documentation', 23 | version: '1.0', 24 | }, 25 | securityDefinitions: { 26 | jwt: { 27 | type: 'apiKey', 28 | name: 'Authorization', 29 | in: 'header', 30 | }, 31 | }, 32 | security: [{ jwt: [] }], 33 | }, 34 | }, 35 | ]); 36 | } 37 | } 38 | Object.seal(Swagger); 39 | -------------------------------------------------------------------------------- /src/routes/UserRoute.ts: -------------------------------------------------------------------------------- 1 | import { UserHandler } from './../handlers/UserHandler'; 2 | import IRoute from './interfaces/IRoute'; 3 | import * as Hapi from 'hapi'; 4 | import * as Joi from 'joi'; 5 | 6 | export class UserRoute implements IRoute { 7 | private userHandler: UserHandler; 8 | 9 | constructor() { 10 | this.userHandler = new UserHandler(); 11 | } 12 | 13 | /** 14 | * Retorna a configuração para a rota POST /user 15 | * @returns Hapi.RouteConfiguration 16 | */ 17 | private login(): Hapi.RouteConfiguration { 18 | return { 19 | path: '/users/login', 20 | method: 'POST', 21 | config: { 22 | handler: async (request: Hapi.Request, reply: any) => { 23 | return await this.userHandler.signIn(request, reply); 24 | }, 25 | auth: false, 26 | description: 'Ativa a sessão de um usuário', 27 | notes: 28 | 'Ativa a sessão de um usuário, para futuramente devolver um token de acesso.', 29 | tags: ['api'], 30 | validate: { 31 | payload: { 32 | name: Joi.string().required(), 33 | password: Joi.string().required(), 34 | }, 35 | }, 36 | }, 37 | }; 38 | } 39 | 40 | /* 41 | * @returns [Returns the Route object for HapiRouter to setup] 42 | * @memberOf HelloWorldRoute 43 | */ 44 | private list(): Hapi.RouteConfiguration { 45 | return { 46 | path: '/users', 47 | method: 'GET', 48 | config: { 49 | handler: async (request: Hapi.Request, reply: any) => { 50 | return await this.userHandler.list(request, reply); 51 | }, 52 | auth: 'jwt', 53 | description: 'Lista todos os usuários', 54 | notes: 'Lista todos os usuário registrados, Coordenadores ou não', 55 | tags: ['api'], 56 | validate: { 57 | headers: Joi.object({ 58 | authorization: Joi.string().required(), 59 | }).unknown(), 60 | }, 61 | }, 62 | }; 63 | } 64 | 65 | /* 66 | * @returns [Returns the Route object for HapiRouter to setup] 67 | * @memberOf HelloWorldRoute 68 | */ 69 | private findOne(): Hapi.RouteConfiguration { 70 | return { 71 | path: '/users/{id}', 72 | method: 'GET', 73 | config: { 74 | handler: async (request: Hapi.Request, reply: any) => { 75 | return await this.userHandler.findOne(request, reply); 76 | }, 77 | auth: 'jwt', 78 | description: 'Obtem um usuário', 79 | notes: 'Obtem um usuário', 80 | tags: ['api'], 81 | validate: { 82 | params: { 83 | id: Joi.string().required(), 84 | }, 85 | headers: Joi.object({ 86 | authorization: Joi.string().required(), 87 | }).unknown(), 88 | }, 89 | }, 90 | }; 91 | } 92 | 93 | /** 94 | * [Retorna a configuração da rota DELETE.] 95 | * @returns [Hapi.RouteConfiguration] 96 | * @memberOf RegionRoute 97 | */ 98 | private remove(): Hapi.RouteConfiguration { 99 | return { 100 | path: '/users/{id}', 101 | method: 'DELETE', 102 | handler: async (request: Hapi.Request, reply: any) => { 103 | return await this.userHandler.remove(request, reply); 104 | }, 105 | config: { 106 | auth: 'jwt', 107 | description: 'Remove um usuário', 108 | notes: 'Remove um usuário', 109 | tags: ['api'], 110 | validate: { 111 | headers: Joi.object({ 112 | authorization: Joi.string().required(), 113 | }).unknown(), 114 | params: { 115 | id: Joi.string().required(), 116 | }, 117 | }, 118 | }, 119 | }; 120 | } 121 | 122 | /** 123 | * [Retorna a configuração da rota DELETE.] 124 | * @returns [Hapi.RouteConfiguration] 125 | * @memberOf RegionRoute 126 | */ 127 | private update(): Hapi.RouteConfiguration { 128 | return { 129 | path: '/users/{id}', 130 | method: 'PUT', 131 | handler: async (request: Hapi.Request, reply: any) => { 132 | return await this.userHandler.update(request, reply); 133 | }, 134 | config: { 135 | auth: 'jwt', 136 | description: 'Altera um usuário', 137 | notes: 'Altera um usuário', 138 | tags: ['api'], 139 | validate: { 140 | headers: Joi.object({ 141 | authorization: Joi.string().required(), 142 | }).unknown(), 143 | payload: { 144 | name: Joi.string(), 145 | password: Joi.string(), 146 | }, 147 | params: { 148 | id: Joi.string().required(), 149 | }, 150 | }, 151 | }, 152 | }; 153 | } 154 | 155 | /** 156 | * [Retorna a configuração da rota POST.] 157 | * @returns [Hapi.RouteConfiguration] 158 | * @memberOf RegionRoute 159 | */ 160 | private create(): Hapi.RouteConfiguration { 161 | return { 162 | path: '/users', 163 | method: 'POST', 164 | handler: async (request: Hapi.Request, reply: any) => { 165 | return await this.userHandler.create(request, reply); 166 | }, 167 | config: { 168 | auth: 'jwt', 169 | description: 'Realiza o cadastro de usuário', 170 | notes: 'Cria um usuário, gerando a hash da senha dele.', 171 | tags: ['api'], 172 | validate: { 173 | payload: { 174 | name: Joi.string().required(), 175 | password: Joi.string() 176 | .required() 177 | .min(6) 178 | .max(12), 179 | }, 180 | headers: Joi.object({ 181 | authorization: Joi.string().required(), 182 | }).unknown(), 183 | }, 184 | }, 185 | }; 186 | } 187 | /** 188 | * Retorna um array com todas as configurações de rotas desse objeto. 189 | * @returns Hapi.RouteConfiguration[] 190 | */ 191 | public routes(): Hapi.RouteConfiguration[] { 192 | return [ 193 | this.login(), 194 | this.list(), 195 | this.findOne(), 196 | this.remove(), 197 | this.update(), 198 | this.create(), 199 | ]; 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/routes/base/BaseRoute.ts: -------------------------------------------------------------------------------- 1 | import { UserRoute } from '../UserRoute'; 2 | import * as Hapi from 'hapi'; 3 | export class BaseRoute { 4 | static routes(): Hapi.RouteConfiguration[] { 5 | return [new UserRoute().routes()].reduce((prev, next) => prev.concat(next)); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/routes/interfaces/IRoute.ts: -------------------------------------------------------------------------------- 1 | import * as Hapi from 'hapi'; 2 | interface IRoute { 3 | /** 4 | * [A function that returns an Array of route objects to use.] 5 | * @returns Function 6 | * @memberOf IRoute 7 | */ 8 | routes(): Hapi.RouteConfiguration[]; 9 | } 10 | export default IRoute; 11 | -------------------------------------------------------------------------------- /src/services/UserService.ts: -------------------------------------------------------------------------------- 1 | import * as bcrypt from 'bcrypt'; 2 | import Base from './base/Base'; 3 | import { User } from '../entities/User'; 4 | import UserSchema from '../db/schemas/UserSchema'; 5 | // const JWT = require('jsonwebtoken'); 6 | import * as Jwt from 'jsonwebtoken'; 7 | 8 | export class UserService extends Base { 9 | constructor() { 10 | super(UserSchema); 11 | } 12 | 13 | generateHash(password: String) { 14 | return bcrypt.hash(password, 10); 15 | } 16 | 17 | async validateHash(user: User, hash: string) { 18 | return await bcrypt.compare(user.password, hash); 19 | } 20 | 21 | async signIn(user: User) { 22 | const { name } = user; 23 | const userDb = (await this.findOne({ name })) as User; 24 | if (!userDb) { 25 | throw new Error('Usuário não encontrado'); 26 | } 27 | 28 | const validHash = await this.validateHash(user, userDb.password); 29 | if (!validHash) throw new Error('Usuário ou senha incorretos'); 30 | 31 | return Jwt.sign(user, process.env.JWT_SECRET || ''); 32 | } 33 | 34 | async create(user: User): Promise { 35 | user.password = await this.generateHash(user.password); 36 | 37 | const existentUser = await this.findOne({ name: user.name }); 38 | if (existentUser) throw new Error('Usuário existente!'); 39 | 40 | const created: any = await super.create(user); 41 | 42 | if (created) { 43 | return { 44 | status: true, 45 | _id: created.id, 46 | }; 47 | } 48 | 49 | return { 50 | status: false, 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/services/base/Base.ts: -------------------------------------------------------------------------------- 1 | import IBase from '../interfaces/IBase'; 2 | import * as mongoose from 'mongoose'; 3 | 4 | class Base implements IBase { 5 | // tslint:disable-next-line:variable-name 6 | public _database: mongoose.Model; 7 | 8 | constructor(database: any) { 9 | this._database = database; 10 | } 11 | async create(item: T): Promise { 12 | const result = await this._database.create(item); 13 | return { status: 'created', id: result._id.toString() }; 14 | } 15 | 16 | async update( 17 | fields: T | {}, 18 | item: T, 19 | upsert: boolean = false, 20 | ): Promise { 21 | const result = await this._database.update(fields, { upsert, $set: item }); 22 | return result; 23 | } 24 | async findOne( 25 | query: T | {}, 26 | lean: boolean = true, 27 | ): Promise { 28 | const result = (await this._database.findOne(query).lean(lean)) as T; 29 | return result; 30 | } 31 | 32 | async list( 33 | query: T | {} = {}, 34 | options: { 35 | skip: Number; 36 | limit: Number; 37 | order: { field: String; order: String }; 38 | }, 39 | ): Promise { 40 | const result = await this._database.find(query, { __v: 0 }, options); 41 | return result; 42 | } 43 | 44 | async find( 45 | query: T | {}, 46 | item: { 47 | skip: Number; 48 | limit: Number; 49 | order: { field: String; order: String } | {}; 50 | }, 51 | ): Promise { 52 | const result = await this._database.find(item, {}, item); 53 | return result; 54 | } 55 | 56 | async remove(id: string): Promise { 57 | const result = await this._database.remove({ _id: id }); 58 | return { status: result }; 59 | } 60 | } 61 | export default Base; 62 | -------------------------------------------------------------------------------- /src/services/interfaces/IBase.ts: -------------------------------------------------------------------------------- 1 | import * as mongoose from 'mongoose'; 2 | 3 | interface IBase { 4 | create(item: T): Promise; 5 | 6 | update(fields: T, item: T, upsert: boolean): Promise; 7 | 8 | list( 9 | query: T | {}, 10 | item: { 11 | skip: Number; 12 | limit: Number; 13 | order: { 14 | field: String; 15 | order: String; 16 | }; 17 | }, 18 | ): Promise; 19 | 20 | findOne(query: T, lean: boolean): Promise; 21 | 22 | find( 23 | query: T, 24 | item: { 25 | skip: Number; 26 | limit: Number; 27 | order: { field: String; order: String }; 28 | }, 29 | ): Promise; 30 | 31 | remove(id: string): Promise; 32 | } 33 | 34 | export default IBase; 35 | -------------------------------------------------------------------------------- /tests/UserRouterTest.ts: -------------------------------------------------------------------------------- 1 | import { TestContext, test } from 'ava'; 2 | import * as assert from 'assert'; 3 | const request = require('hapi-test-request'); 4 | 5 | import app from './../app'; 6 | import IRoute from '../src/routes/interfaces/IRoute'; 7 | import * as Hapi from 'hapi'; 8 | import { User } from '../src/entities/User'; 9 | import { UserService } from '../src/services/UserService'; 10 | import * as mongoose from 'mongoose'; 11 | import * as dotenv from 'dotenv'; 12 | 13 | if (process.env.ENVIRONMENT !== 'PROD') { 14 | dotenv.config({ path: './config/.env.dev' }); 15 | } else { 16 | dotenv.config({ path: './config/.env.prod' }); 17 | } 18 | 19 | let server: Hapi.Server; 20 | let id: string; 21 | const service = new UserService(); 22 | 23 | const MOCK_USER = { 24 | id: undefined, 25 | name: `teste4@test.com`, 26 | password: '1234565', 27 | }; 28 | const MOCK_INSERT = { 29 | name: `${new Date().getTime()}teste4@test.com`, 30 | password: '123123', 31 | }; 32 | const MOCKED_TOKEN = 33 | // tslint:disable-next-line:max-line-length 34 | 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiRXJpY2sgV2VuZGVsIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJpYXQiOjE1MTEyMjA2ODl9.CaofBWm56rjM7Pe11-OHCJu0PvK7AJZ2AkZbRFTQ7mk'; 35 | 36 | test.before(async () => { 37 | const item = await app(); 38 | server = request(item); 39 | }); 40 | 41 | test.before(async () => { 42 | let result: any = await service.findOne({ name: MOCK_USER.name }); 43 | if (result) { 44 | id = result._id; 45 | return; 46 | } 47 | 48 | result = await service.create(MOCK_USER); 49 | id = result.id; 50 | }); 51 | 52 | test('GET /users/login - deve realizar login e obter token', async ( 53 | t: TestContext, 54 | ) => { 55 | const req: Object = { 56 | method: 'POST', 57 | url: '/users/login', 58 | payload: JSON.stringify({ 59 | name: MOCK_USER.name, 60 | password: MOCK_USER.password, 61 | }), 62 | }; 63 | const res = await server.call(req); 64 | t.true(res.result.length >= 160); 65 | }); 66 | 67 | test('GET /users - listar usuarios', async (t: TestContext) => { 68 | const req: Object = { 69 | method: 'GET', 70 | url: '/users', 71 | headers: { 72 | Authorization: `${MOCKED_TOKEN}`, 73 | }, 74 | }; 75 | 76 | const result = await server.call(req); 77 | const payload = JSON.parse(result.payload); 78 | t.true(payload.length >= 0); 79 | }); 80 | 81 | test('GET /users/{id} - obter um usuario', async (t: TestContext) => { 82 | const req: Object = { 83 | method: 'GET', 84 | url: `/users/${id}`, 85 | headers: { 86 | Authorization: `${MOCKED_TOKEN}`, 87 | }, 88 | }; 89 | 90 | const result = await server.call(req); 91 | const { name } = JSON.parse(result.payload); 92 | 93 | t.deepEqual(name, MOCK_USER.name); 94 | }); 95 | 96 | test('POST /users - cadastrar usuario', async (t: TestContext) => { 97 | const req: Object = { 98 | method: 'POST', 99 | url: '/users', 100 | headers: { 101 | Authorization: `${MOCKED_TOKEN}`, 102 | }, 103 | payload: MOCK_INSERT, 104 | }; 105 | 106 | const result = await server.call(req); 107 | const payload = JSON.parse(result.payload); 108 | t.true(payload.status); 109 | }); 110 | 111 | test('PUT /users/${id} - Atualizar usuario', async (t: TestContext) => { 112 | const user: any = await service.create({ 113 | name: 'Test2' + new Date().getTime(), 114 | password: '123456', 115 | }); 116 | const req: Object = { 117 | method: 'PUT', 118 | url: `/users/${user._id}`, 119 | headers: { 120 | Authorization: `${MOCKED_TOKEN}`, 121 | }, 122 | payload: { 123 | name: `${new Date().getTime()}updated@test.com`, 124 | }, 125 | }; 126 | 127 | const result = await server.call(req); 128 | const payload = JSON.parse(result.payload); 129 | t.true(payload.ok === 1); 130 | }); 131 | 132 | test.after('DELETE /users/${id} - Remover usuarios', async (t: TestContext) => { 133 | const user: any = await service.create({ 134 | name: 'Test2' + new Date().getTime(), 135 | password: '123456', 136 | }); 137 | const req: Object = { 138 | method: 'DELETE', 139 | url: `/users/${user._id}`, 140 | headers: { 141 | Authorization: `${MOCKED_TOKEN}`, 142 | }, 143 | }; 144 | const res = await server.call(req); 145 | t.true(res.result.status.result.ok === 1); 146 | }); 147 | 148 | // test.after('Remove mocked data from db', async (t: TestContext) => { 149 | // const item: any = await service.findOne({ name: MOCK_INSERT.name }); 150 | // await service.remove(item._id); 151 | // }); 152 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": 5 | "es2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */, 6 | "module": 7 | "commonjs" /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, 8 | // "lib": [], /* Specify library files to be included in the compilation: */ 9 | // "allowJs": true, /* Allow javascript files to be compiled. */ 10 | // "checkJs": true, /* Report errors in .js files. */ 11 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 12 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 13 | "sourceMap": true /* Generates corresponding '.map' file. */, 14 | // "outFile": "./", /* Concatenate and emit output to single file. */ 15 | "outDir": "lib/" /* Redirect output structure to the directory. */, 16 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 17 | // "removeComments": true, /* Do not emit comments to output. */ 18 | // "noEmit": true, /* Do not emit outputs. */ 19 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 20 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 21 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 22 | 23 | /* Strict Type-Checking Options */ 24 | "strict": true /* Enable all strict type-checking options. */ 25 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 26 | // "strictNullChecks": true, /* Enable strict null checks. */ 27 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 28 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 29 | 30 | /* Additional Checks */ 31 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 32 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 33 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 34 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 35 | 36 | /* Module Resolution Options */ 37 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 38 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 39 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 40 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 41 | // "typeRoots": [], /* List of folders to include type definitions from. */ 42 | // "types": [], /* Type declaration files to be included in compilation. */ 43 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 44 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 45 | 46 | /* Source Map Options */ 47 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 48 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ 49 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 50 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 51 | 52 | /* Experimental Options */ 53 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 54 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */ 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": ["tslint-config-airbnb"], 4 | "jsRules": { "ter-arrow-parens": "0" }, 5 | "rules": {}, 6 | "rulesDirectory": [] 7 | } 8 | --------------------------------------------------------------------------------