parent
99e08bb02f
commit
6b009b7c22
@ -0,0 +1,10 @@ |
|||||||
|
NODE_ENV=development |
||||||
|
|
||||||
|
DB_HOST=localhost |
||||||
|
DB_PORT=3306 |
||||||
|
DB_USERNAME=root |
||||||
|
DB_PASSWORD=init00!! |
||||||
|
DB_DATABASE=boilerplate_db |
||||||
|
|
||||||
|
JWT_SECRET=jwt-secret |
||||||
|
JWT_EXPIRES_IN=600s |
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"singleQuote": true, |
||||||
|
"trailingComma": "all" |
||||||
|
} |
@ -0,0 +1,98 @@ |
|||||||
|
<p align="center"> |
||||||
|
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a> |
||||||
|
</p> |
||||||
|
|
||||||
|
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 |
||||||
|
[circleci-url]: https://circleci.com/gh/nestjs/nest |
||||||
|
|
||||||
|
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p> |
||||||
|
<p align="center"> |
||||||
|
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a> |
||||||
|
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a> |
||||||
|
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a> |
||||||
|
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a> |
||||||
|
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a> |
||||||
|
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a> |
||||||
|
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a> |
||||||
|
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg" alt="Donate us"/></a> |
||||||
|
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a> |
||||||
|
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow" alt="Follow us on Twitter"></a> |
||||||
|
</p> |
||||||
|
<!--[](https://opencollective.com/nest#backer) |
||||||
|
[](https://opencollective.com/nest#sponsor)--> |
||||||
|
|
||||||
|
## Description |
||||||
|
|
||||||
|
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. |
||||||
|
|
||||||
|
## Project setup |
||||||
|
|
||||||
|
```bash |
||||||
|
$ npm install |
||||||
|
``` |
||||||
|
|
||||||
|
## Compile and run the project |
||||||
|
|
||||||
|
```bash |
||||||
|
# development |
||||||
|
$ npm run start |
||||||
|
|
||||||
|
# watch mode |
||||||
|
$ npm run start:dev |
||||||
|
|
||||||
|
# production mode |
||||||
|
$ npm run start:prod |
||||||
|
``` |
||||||
|
|
||||||
|
## Run tests |
||||||
|
|
||||||
|
```bash |
||||||
|
# unit tests |
||||||
|
$ npm run test |
||||||
|
|
||||||
|
# e2e tests |
||||||
|
$ npm run test:e2e |
||||||
|
|
||||||
|
# test coverage |
||||||
|
$ npm run test:cov |
||||||
|
``` |
||||||
|
|
||||||
|
## Deployment |
||||||
|
|
||||||
|
When you're ready to deploy your NestJS application to production, there are some key steps you can take to ensure it runs as efficiently as possible. Check out the [deployment documentation](https://docs.nestjs.com/deployment) for more information. |
||||||
|
|
||||||
|
If you are looking for a cloud-based platform to deploy your NestJS application, check out [Mau](https://mau.nestjs.com), our official platform for deploying NestJS applications on AWS. Mau makes deployment straightforward and fast, requiring just a few simple steps: |
||||||
|
|
||||||
|
```bash |
||||||
|
$ npm install -g @nestjs/mau |
||||||
|
$ mau deploy |
||||||
|
``` |
||||||
|
|
||||||
|
With Mau, you can deploy your application in just a few clicks, allowing you to focus on building features rather than managing infrastructure. |
||||||
|
|
||||||
|
## Resources |
||||||
|
|
||||||
|
Check out a few resources that may come in handy when working with NestJS: |
||||||
|
|
||||||
|
- Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework. |
||||||
|
- For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy). |
||||||
|
- To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/). |
||||||
|
- Deploy your application to AWS with the help of [NestJS Mau](https://mau.nestjs.com) in just a few clicks. |
||||||
|
- Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com). |
||||||
|
- Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com). |
||||||
|
- To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs). |
||||||
|
- Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com). |
||||||
|
|
||||||
|
## Support |
||||||
|
|
||||||
|
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). |
||||||
|
|
||||||
|
## Stay in touch |
||||||
|
|
||||||
|
- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec) |
||||||
|
- Website - [https://nestjs.com](https://nestjs.com/) |
||||||
|
- Twitter - [@nestframework](https://twitter.com/nestframework) |
||||||
|
|
||||||
|
## License |
||||||
|
|
||||||
|
Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE). |
@ -0,0 +1,6 @@ |
|||||||
|
import { AppService } from './app.service'; |
||||||
|
export declare class AppController { |
||||||
|
private readonly appService; |
||||||
|
constructor(appService: AppService); |
||||||
|
getHello(): string; |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) { |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.AppController = void 0; |
||||||
|
const common_1 = require("@nestjs/common"); |
||||||
|
const app_service_1 = require("./app.service"); |
||||||
|
let AppController = class AppController { |
||||||
|
appService; |
||||||
|
constructor(appService) { |
||||||
|
this.appService = appService; |
||||||
|
} |
||||||
|
getHello() { |
||||||
|
return this.appService.getHello(); |
||||||
|
} |
||||||
|
}; |
||||||
|
exports.AppController = AppController; |
||||||
|
__decorate([ |
||||||
|
(0, common_1.Get)(), |
||||||
|
__metadata("design:type", Function), |
||||||
|
__metadata("design:paramtypes", []), |
||||||
|
__metadata("design:returntype", String) |
||||||
|
], AppController.prototype, "getHello", null); |
||||||
|
exports.AppController = AppController = __decorate([ |
||||||
|
(0, common_1.Controller)(), |
||||||
|
__metadata("design:paramtypes", [app_service_1.AppService]) |
||||||
|
], AppController); |
||||||
|
//# sourceMappingURL=app.controller.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"app.controller.js","sourceRoot":"","sources":["../src/app.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiD;AACjD,+CAA2C;AAGpC,IAAM,aAAa,GAAnB,MAAM,aAAa;IACK;IAA7B,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAGvD,QAAQ;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;IACpC,CAAC;CACF,CAAA;AAPY,sCAAa;AAIxB;IADC,IAAA,YAAG,GAAE;;;;6CAGL;wBANU,aAAa;IADzB,IAAA,mBAAU,GAAE;qCAE8B,wBAAU;GADxC,aAAa,CAOzB"} |
@ -0,0 +1,2 @@ |
|||||||
|
export declare class AppModule { |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.AppModule = void 0; |
||||||
|
const common_1 = require("@nestjs/common"); |
||||||
|
const app_controller_1 = require("./app.controller"); |
||||||
|
const app_service_1 = require("./app.service"); |
||||||
|
const config_1 = require("@nestjs/config"); |
||||||
|
const typeorm_1 = require("@nestjs/typeorm"); |
||||||
|
const path_1 = require("path"); |
||||||
|
const auth_module_1 = require("./auth/auth.module"); |
||||||
|
const users_module_1 = require("./users/users.module"); |
||||||
|
const jwt_1 = require("@nestjs/jwt"); |
||||||
|
let AppModule = class AppModule { |
||||||
|
}; |
||||||
|
exports.AppModule = AppModule; |
||||||
|
exports.AppModule = AppModule = __decorate([ |
||||||
|
(0, common_1.Module)({ |
||||||
|
imports: [ |
||||||
|
config_1.ConfigModule.forRoot({ isGlobal: true }), |
||||||
|
typeorm_1.TypeOrmModule.forRootAsync({ |
||||||
|
imports: [config_1.ConfigModule], |
||||||
|
inject: [config_1.ConfigService], |
||||||
|
useFactory: async (config) => ({ |
||||||
|
type: 'mysql', |
||||||
|
host: config.get('DB_HOST'), |
||||||
|
port: parseInt(config.get('DB_PORT', '3306'), 10), |
||||||
|
username: config.get('DB_USERNAME'), |
||||||
|
password: config.get('DB_PASSWORD'), |
||||||
|
database: config.get('DB_DATABASE'), |
||||||
|
entities: [(0, path_1.join)(__dirname, '**', '*.entity.{ts,js}')], |
||||||
|
synchronize: config.get('NODE_ENV') !== 'production', |
||||||
|
autoLoadEntities: true, |
||||||
|
logging: true, |
||||||
|
}), |
||||||
|
}), auth_module_1.AuthModule, users_module_1.UsersModule |
||||||
|
], |
||||||
|
controllers: [app_controller_1.AppController], |
||||||
|
providers: [app_service_1.AppService, jwt_1.JwtService], |
||||||
|
}) |
||||||
|
], AppModule); |
||||||
|
//# sourceMappingURL=app.module.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,qDAAiD;AACjD,+CAA2C;AAC3C,2CAA6D;AAC7D,6CAAgD;AAChD,+BAA4B;AAC5B,oDAAgD;AAChD,uDAAmD;AACnD,qCAAyC;AAyBlC,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAvBrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACL,qBAAY,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACxC,uBAAa,CAAC,YAAY,CAAC;gBAC3B,OAAO,EAAE,CAAC,qBAAY,CAAC;gBACvB,MAAM,EAAE,CAAC,sBAAa,CAAC;gBACvB,UAAU,EAAE,KAAK,EAAE,MAAqB,EAAE,EAAE,CAAC,CAAC;oBAC5C,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,MAAM,CAAC,GAAG,CAAS,SAAS,CAAC;oBACnC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAS,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;oBACzD,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAS,aAAa,CAAC;oBAC3C,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAS,aAAa,CAAC;oBAC3C,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAS,aAAa,CAAC;oBAC3C,QAAQ,EAAE,CAAC,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC;oBACrD,WAAW,EAAE,MAAM,CAAC,GAAG,CAAS,UAAU,CAAC,KAAK,YAAY;oBAC5D,gBAAgB,EAAE,IAAI;oBACtB,OAAO,EAAE,IAAI;iBACd,CAAC;aACH,CAAC,EAAE,wBAAU,EAAE,0BAAW;SAC5B;QACD,WAAW,EAAE,CAAC,8BAAa,CAAC;QAC5B,SAAS,EAAE,CAAC,wBAAU,EAAE,gBAAU,CAAC;KACpC,CAAC;GACW,SAAS,CAAG"} |
@ -0,0 +1,3 @@ |
|||||||
|
export declare class AppService { |
||||||
|
getHello(): string; |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.AppService = void 0; |
||||||
|
const common_1 = require("@nestjs/common"); |
||||||
|
let AppService = class AppService { |
||||||
|
getHello() { |
||||||
|
return 'Hello World!'; |
||||||
|
} |
||||||
|
}; |
||||||
|
exports.AppService = AppService; |
||||||
|
exports.AppService = AppService = __decorate([ |
||||||
|
(0, common_1.Injectable)() |
||||||
|
], AppService); |
||||||
|
//# sourceMappingURL=app.service.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"app.service.js","sourceRoot":"","sources":["../src/app.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAGrC,IAAM,UAAU,GAAhB,MAAM,UAAU;IACrB,QAAQ;QACN,OAAO,cAAc,CAAC;IACxB,CAAC;CACF,CAAA;AAJY,gCAAU;qBAAV,UAAU;IADtB,IAAA,mBAAU,GAAE;GACA,UAAU,CAItB"} |
@ -0,0 +1,11 @@ |
|||||||
|
import { AuthService } from './auth.service'; |
||||||
|
import { CreateUserDto } from 'src/users/dto/create-user.dto'; |
||||||
|
import { LoginUserDto } from 'src/auth/dto/login-user.dto'; |
||||||
|
export declare class AuthController { |
||||||
|
private readonly authService; |
||||||
|
constructor(authService: AuthService); |
||||||
|
signup(dto: CreateUserDto): Promise<import("../users/user.entity").User>; |
||||||
|
login(dto: LoginUserDto): Promise<{ |
||||||
|
access_token: string; |
||||||
|
}>; |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) { |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); |
||||||
|
}; |
||||||
|
var __param = (this && this.__param) || function (paramIndex, decorator) { |
||||||
|
return function (target, key) { decorator(target, key, paramIndex); } |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.AuthController = void 0; |
||||||
|
const common_1 = require("@nestjs/common"); |
||||||
|
const auth_service_1 = require("./auth.service"); |
||||||
|
const create_user_dto_1 = require("../users/dto/create-user.dto"); |
||||||
|
const login_user_dto_1 = require("./dto/login-user.dto"); |
||||||
|
let AuthController = class AuthController { |
||||||
|
authService; |
||||||
|
constructor(authService) { |
||||||
|
this.authService = authService; |
||||||
|
} |
||||||
|
async signup(dto) { |
||||||
|
return this.authService.signup(dto); |
||||||
|
} |
||||||
|
async login(dto) { |
||||||
|
return this.authService.login(dto); |
||||||
|
} |
||||||
|
}; |
||||||
|
exports.AuthController = AuthController; |
||||||
|
__decorate([ |
||||||
|
(0, common_1.Post)('signup'), |
||||||
|
__param(0, (0, common_1.Body)()), |
||||||
|
__metadata("design:type", Function), |
||||||
|
__metadata("design:paramtypes", [create_user_dto_1.CreateUserDto]), |
||||||
|
__metadata("design:returntype", Promise) |
||||||
|
], AuthController.prototype, "signup", null); |
||||||
|
__decorate([ |
||||||
|
(0, common_1.Post)('login'), |
||||||
|
__param(0, (0, common_1.Body)()), |
||||||
|
__metadata("design:type", Function), |
||||||
|
__metadata("design:paramtypes", [login_user_dto_1.LoginUserDto]), |
||||||
|
__metadata("design:returntype", Promise) |
||||||
|
], AuthController.prototype, "login", null); |
||||||
|
exports.AuthController = AuthController = __decorate([ |
||||||
|
(0, common_1.Controller)('auth'), |
||||||
|
__metadata("design:paramtypes", [auth_service_1.AuthService]) |
||||||
|
], AuthController); |
||||||
|
//# sourceMappingURL=auth.controller.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"auth.controller.js","sourceRoot":"","sources":["../../src/auth/auth.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAwD;AACxD,iDAA6C;AAC7C,kEAA8D;AAC9D,yDAA2D;AAGpD,IAAM,cAAc,GAApB,MAAM,cAAc;IACM;IAA7B,YAA6B,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAG,CAAC;IAGnD,AAAN,KAAK,CAAC,MAAM,CAAS,GAAkB;QACnC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAGK,AAAN,KAAK,CAAC,KAAK,CAAS,GAAiB;QACjC,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC;CACJ,CAAA;AAZY,wCAAc;AAIjB;IADL,IAAA,aAAI,EAAC,QAAQ,CAAC;IACD,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAM,+BAAa;;4CAEtC;AAGK;IADL,IAAA,aAAI,EAAC,OAAO,CAAC;IACD,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAM,6BAAY;;2CAEpC;yBAXQ,cAAc;IAD1B,IAAA,mBAAU,EAAC,MAAM,CAAC;qCAE2B,0BAAW;GAD5C,cAAc,CAY1B"} |
@ -0,0 +1,2 @@ |
|||||||
|
export declare class AuthModule { |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.AuthModule = void 0; |
||||||
|
const common_1 = require("@nestjs/common"); |
||||||
|
const auth_service_1 = require("./auth.service"); |
||||||
|
const auth_controller_1 = require("./auth.controller"); |
||||||
|
const users_module_1 = require("../users/users.module"); |
||||||
|
const jwt_1 = require("@nestjs/jwt"); |
||||||
|
const config_1 = require("@nestjs/config"); |
||||||
|
const passport_1 = require("@nestjs/passport"); |
||||||
|
let AuthModule = class AuthModule { |
||||||
|
}; |
||||||
|
exports.AuthModule = AuthModule; |
||||||
|
exports.AuthModule = AuthModule = __decorate([ |
||||||
|
(0, common_1.Module)({ |
||||||
|
imports: [ |
||||||
|
users_module_1.UsersModule, |
||||||
|
passport_1.PassportModule, |
||||||
|
config_1.ConfigModule, |
||||||
|
jwt_1.JwtModule.registerAsync({ |
||||||
|
imports: [config_1.ConfigModule], |
||||||
|
inject: [config_1.ConfigService], |
||||||
|
useFactory: async (configService) => ({ |
||||||
|
secret: configService.get('JWT_SECRET'), |
||||||
|
signOptions: { |
||||||
|
expiresIn: configService.get('JWT_EXPIRES_IN') || '60s', |
||||||
|
}, |
||||||
|
}) |
||||||
|
}) |
||||||
|
], |
||||||
|
providers: [auth_service_1.AuthService], |
||||||
|
controllers: [auth_controller_1.AuthController] |
||||||
|
}) |
||||||
|
], AuthModule); |
||||||
|
//# sourceMappingURL=auth.module.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../../src/auth/auth.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,iDAA6C;AAC7C,uDAAmD;AACnD,wDAAqD;AACrD,qCAAwC;AACxC,2CAA6D;AAC7D,+CAAkD;AAqB3C,IAAM,UAAU,GAAhB,MAAM,UAAU;CAAG,CAAA;AAAb,gCAAU;qBAAV,UAAU;IAnBtB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,0BAAW;YACX,yBAAc;YACd,qBAAY;YACZ,eAAS,CAAC,aAAa,CAAC;gBACtB,OAAO,EAAE,CAAC,qBAAY,CAAC;gBACvB,MAAM,EAAE,CAAC,sBAAa,CAAC;gBACvB,UAAU,EAAE,KAAK,EAAE,aAA4B,EAAE,EAAE,CAAC,CAAC;oBACnD,MAAM,EAAE,aAAa,CAAC,GAAG,CAAS,YAAY,CAAC;oBAC/C,WAAW,EAAE;wBACX,SAAS,EAAE,aAAa,CAAC,GAAG,CAAS,gBAAgB,CAAC,IAAI,KAAK;qBAChE;iBACF,CAAC;aACH,CAAC;SACH;QACD,SAAS,EAAE,CAAC,0BAAW,CAAC;QACxB,WAAW,EAAE,CAAC,gCAAc,CAAC;KAC9B,CAAC;GACW,UAAU,CAAG"} |
@ -0,0 +1,14 @@ |
|||||||
|
import { JwtService } from '@nestjs/jwt'; |
||||||
|
import { UsersService } from 'src/users/users.service'; |
||||||
|
import { LoginUserDto } from 'src/auth/dto/login-user.dto'; |
||||||
|
import { CreateUserDto } from 'src/users/dto/create-user.dto'; |
||||||
|
export declare class AuthService { |
||||||
|
private userService; |
||||||
|
private jwtService; |
||||||
|
constructor(userService: UsersService, jwtService: JwtService); |
||||||
|
validateUser(name: string, password: string): Promise<any>; |
||||||
|
login(dto: LoginUserDto): Promise<{ |
||||||
|
access_token: string; |
||||||
|
}>; |
||||||
|
signup(dto: CreateUserDto): Promise<import("../users/user.entity").User>; |
||||||
|
} |
@ -0,0 +1,64 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) { |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.AuthService = void 0; |
||||||
|
const common_1 = require("@nestjs/common"); |
||||||
|
const jwt_1 = require("@nestjs/jwt"); |
||||||
|
const users_service_1 = require("../users/users.service"); |
||||||
|
const bcrypt = require("bcrypt"); |
||||||
|
let AuthService = class AuthService { |
||||||
|
userService; |
||||||
|
jwtService; |
||||||
|
constructor(userService, jwtService) { |
||||||
|
this.userService = userService; |
||||||
|
this.jwtService = jwtService; |
||||||
|
} |
||||||
|
async validateUser(name, password) { |
||||||
|
const user = await this.userService.findByName(name); |
||||||
|
if (user && await bcrypt.compare(password, user.password)) { |
||||||
|
const { password, ...rest } = user; |
||||||
|
return rest; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
async login(dto) { |
||||||
|
try { |
||||||
|
const user = await this.userService.findByName(dto.name); |
||||||
|
if (!user) |
||||||
|
throw new common_1.UnauthorizedException('Login failed'); |
||||||
|
const passwordCheck = await bcrypt.compare(dto.password, user.password); |
||||||
|
if (!passwordCheck) |
||||||
|
throw new common_1.UnauthorizedException('Login failed'); |
||||||
|
const payload = { username: user.name, sub: user.id }; |
||||||
|
return { access_token: this.jwtService.sign(payload) }; |
||||||
|
} |
||||||
|
catch (error) { |
||||||
|
if (error instanceof common_1.UnauthorizedException) |
||||||
|
throw error; |
||||||
|
throw new common_1.InternalServerErrorException('Login failed (Internal)'); |
||||||
|
} |
||||||
|
} |
||||||
|
async signup(dto) { |
||||||
|
try { |
||||||
|
const hashed = await bcrypt.hash(dto.password, 10); |
||||||
|
return this.userService.create({ ...dto, password: hashed }); |
||||||
|
} |
||||||
|
catch (error) { |
||||||
|
throw new common_1.BadRequestException('Signup failed'); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
exports.AuthService = AuthService; |
||||||
|
exports.AuthService = AuthService = __decorate([ |
||||||
|
(0, common_1.Injectable)(), |
||||||
|
__metadata("design:paramtypes", [users_service_1.UsersService, jwt_1.JwtService]) |
||||||
|
], AuthService); |
||||||
|
//# sourceMappingURL=auth.service.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../src/auth/auth.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAsH;AACtH,qCAAyC;AACzC,0DAAuD;AACvD,iCAAgC;AAKzB,IAAM,WAAW,GAAjB,MAAM,WAAW;IACA;IAAmC;IAAvD,YAAoB,WAAyB,EAAU,UAAsB;QAAzD,gBAAW,GAAX,WAAW,CAAc;QAAU,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAEjF,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,QAAgB;QAC7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,IAAI,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;YAEnC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAiB;QACzB,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,8BAAqB,CAAC,cAAc,CAAC,CAAC;YAE3D,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxE,IAAI,CAAC,aAAa;gBAAE,MAAM,IAAI,8BAAqB,CAAC,cAAc,CAAC,CAAC;YAEpE,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;YACtD,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,KAAK,YAAY,8BAAqB;gBAAE,MAAM,KAAK,CAAC;YAExD,MAAM,IAAI,qCAA4B,CAAC,yBAAyB,CAAC,CAAC;QACtE,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAkB;QAC3B,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,4BAAmB,CAAC,eAAe,CAAC,CAAC;QACnD,CAAC;IAEL,CAAC;CACJ,CAAA;AAxCY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;qCAEwB,4BAAY,EAAsB,gBAAU;GADpE,WAAW,CAwCvB"} |
@ -0,0 +1,4 @@ |
|||||||
|
export declare class LoginUserDto { |
||||||
|
readonly name: string; |
||||||
|
readonly password: string; |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) { |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.LoginUserDto = void 0; |
||||||
|
const class_validator_1 = require("class-validator"); |
||||||
|
class LoginUserDto { |
||||||
|
name; |
||||||
|
password; |
||||||
|
} |
||||||
|
exports.LoginUserDto = LoginUserDto; |
||||||
|
__decorate([ |
||||||
|
(0, class_validator_1.IsString)(), |
||||||
|
__metadata("design:type", String) |
||||||
|
], LoginUserDto.prototype, "name", void 0); |
||||||
|
__decorate([ |
||||||
|
(0, class_validator_1.IsString)(), |
||||||
|
(0, class_validator_1.MinLength)(4), |
||||||
|
__metadata("design:type", String) |
||||||
|
], LoginUserDto.prototype, "password", void 0); |
||||||
|
//# sourceMappingURL=login-user.dto.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"login-user.dto.js","sourceRoot":"","sources":["../../../src/auth/dto/login-user.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAsD;AAEtD,MAAa,YAAY;IAEZ,IAAI,CAAS;IAIb,QAAQ,CAAS;CAC7B;AAPD,oCAOC;AALY;IADR,IAAA,0BAAQ,GAAE;;0CACW;AAIb;IAFR,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,CAAC,CAAC;;8CACa"} |
@ -0,0 +1,4 @@ |
|||||||
|
export declare abstract class TimestampedEntity { |
||||||
|
createdAt: Date; |
||||||
|
updatedAt: Date; |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) { |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.TimestampedEntity = void 0; |
||||||
|
const typeorm_1 = require("typeorm"); |
||||||
|
class TimestampedEntity { |
||||||
|
createdAt; |
||||||
|
updatedAt; |
||||||
|
} |
||||||
|
exports.TimestampedEntity = TimestampedEntity; |
||||||
|
__decorate([ |
||||||
|
(0, typeorm_1.CreateDateColumn)({ type: 'timestamp' }), |
||||||
|
__metadata("design:type", Date) |
||||||
|
], TimestampedEntity.prototype, "createdAt", void 0); |
||||||
|
__decorate([ |
||||||
|
(0, typeorm_1.UpdateDateColumn)({ type: 'timestamp' }), |
||||||
|
__metadata("design:type", Date) |
||||||
|
], TimestampedEntity.prototype, "updatedAt", void 0); |
||||||
|
//# sourceMappingURL=timestamped.entity.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"timestamped.entity.js","sourceRoot":"","sources":["../../../src/common/entities/timestamped.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAA6D;AAE7D,MAAsB,iBAAiB;IAEnC,SAAS,CAAO;IAGhB,SAAS,CAAO;CACnB;AAND,8CAMC;AAJG;IADC,IAAA,0BAAgB,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;8BAC7B,IAAI;oDAAC;AAGhB;IADC,IAAA,0BAAgB,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;8BAC7B,IAAI;oDAAC"} |
@ -0,0 +1 @@ |
|||||||
|
export {}; |
@ -0,0 +1,17 @@ |
|||||||
|
"use strict"; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
const core_1 = require("@nestjs/core"); |
||||||
|
const app_module_1 = require("./app.module"); |
||||||
|
const common_1 = require("@nestjs/common"); |
||||||
|
async function bootstrap() { |
||||||
|
const app = await core_1.NestFactory.create(app_module_1.AppModule); |
||||||
|
app.enableCors(); |
||||||
|
app.useGlobalPipes(new common_1.ValidationPipe({ |
||||||
|
whitelist: true, |
||||||
|
forbidNonWhitelisted: true, |
||||||
|
transform: true, |
||||||
|
})); |
||||||
|
await app.listen(process.env.PORT ?? 3000); |
||||||
|
} |
||||||
|
bootstrap(); |
||||||
|
//# sourceMappingURL=main.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;AACzC,2CAAgD;AAEhD,KAAK,UAAU,SAAS;IACtB,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,CAAC;IAChD,GAAG,CAAC,UAAU,EAAE,CAAC;IACjB,GAAG,CAAC,cAAc,CAChB,IAAI,uBAAc,CAAC;QACjB,SAAS,EAAE,IAAI;QACf,oBAAoB,EAAE,IAAI;QAC1B,SAAS,EAAE,IAAI;KAChB,CAAC,CACH,CAAA;IACD,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAC7C,CAAC;AACD,SAAS,EAAE,CAAC"} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,5 @@ |
|||||||
|
export declare class CreateUserDto { |
||||||
|
readonly name: string; |
||||||
|
readonly email?: string; |
||||||
|
readonly password: string; |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) { |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.CreateUserDto = void 0; |
||||||
|
const class_validator_1 = require("class-validator"); |
||||||
|
class CreateUserDto { |
||||||
|
name; |
||||||
|
email; |
||||||
|
password; |
||||||
|
} |
||||||
|
exports.CreateUserDto = CreateUserDto; |
||||||
|
__decorate([ |
||||||
|
(0, class_validator_1.IsString)(), |
||||||
|
__metadata("design:type", String) |
||||||
|
], CreateUserDto.prototype, "name", void 0); |
||||||
|
__decorate([ |
||||||
|
(0, class_validator_1.IsOptional)(), |
||||||
|
(0, class_validator_1.IsEmail)(), |
||||||
|
__metadata("design:type", String) |
||||||
|
], CreateUserDto.prototype, "email", void 0); |
||||||
|
__decorate([ |
||||||
|
(0, class_validator_1.IsString)(), |
||||||
|
(0, class_validator_1.MinLength)(4), |
||||||
|
__metadata("design:type", String) |
||||||
|
], CreateUserDto.prototype, "password", void 0); |
||||||
|
//# sourceMappingURL=create-user.dto.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"create-user.dto.js","sourceRoot":"","sources":["../../../src/users/dto/create-user.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAA2E;AAE3E,MAAa,aAAa;IAEb,IAAI,CAAS;IAIb,KAAK,CAAU;IAIf,QAAQ,CAAS;CAC7B;AAXD,sCAWC;AATY;IADR,IAAA,0BAAQ,GAAE;;2CACW;AAIb;IAFR,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,GAAE;;4CACc;AAIf;IAFR,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,CAAC,CAAC;;+CACa"} |
@ -0,0 +1,7 @@ |
|||||||
|
import { TimestampedEntity } from "src/common/entities/timestamped.entity"; |
||||||
|
export declare class User extends TimestampedEntity { |
||||||
|
id: number; |
||||||
|
name: string; |
||||||
|
email?: string; |
||||||
|
password: string; |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) { |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.User = void 0; |
||||||
|
const timestamped_entity_1 = require("../common/entities/timestamped.entity"); |
||||||
|
const typeorm_1 = require("typeorm"); |
||||||
|
let User = class User extends timestamped_entity_1.TimestampedEntity { |
||||||
|
id; |
||||||
|
name; |
||||||
|
email; |
||||||
|
password; |
||||||
|
}; |
||||||
|
exports.User = User; |
||||||
|
__decorate([ |
||||||
|
(0, typeorm_1.PrimaryGeneratedColumn)(), |
||||||
|
__metadata("design:type", Number) |
||||||
|
], User.prototype, "id", void 0); |
||||||
|
__decorate([ |
||||||
|
(0, typeorm_1.Column)({ unique: true }), |
||||||
|
__metadata("design:type", String) |
||||||
|
], User.prototype, "name", void 0); |
||||||
|
__decorate([ |
||||||
|
(0, typeorm_1.Column)({ unique: true, nullable: true }), |
||||||
|
__metadata("design:type", String) |
||||||
|
], User.prototype, "email", void 0); |
||||||
|
__decorate([ |
||||||
|
(0, typeorm_1.Column)(), |
||||||
|
__metadata("design:type", String) |
||||||
|
], User.prototype, "password", void 0); |
||||||
|
exports.User = User = __decorate([ |
||||||
|
(0, typeorm_1.Entity)() |
||||||
|
], User); |
||||||
|
//# sourceMappingURL=user.entity.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"user.entity.js","sourceRoot":"","sources":["../../src/users/user.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8EAA2E;AAC3E,qCAAiE;AAG1D,IAAM,IAAI,GAAV,MAAM,IAAK,SAAQ,sCAAiB;IAEvC,EAAE,CAAS;IAGX,IAAI,CAAS;IAGb,KAAK,CAAU;IAGf,QAAQ,CAAS;CACpB,CAAA;AAZY,oBAAI;AAEb;IADC,IAAA,gCAAsB,GAAE;;gCACd;AAGX;IADC,IAAA,gBAAM,EAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;;kCACZ;AAGb;IADC,IAAA,gBAAM,EAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;mCAC1B;AAGf;IADC,IAAA,gBAAM,GAAE;;sCACQ;eAXR,IAAI;IADhB,IAAA,gBAAM,GAAE;GACI,IAAI,CAYhB"} |
@ -0,0 +1,2 @@ |
|||||||
|
export declare class UsersModule { |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.UsersModule = void 0; |
||||||
|
const common_1 = require("@nestjs/common"); |
||||||
|
const users_service_1 = require("./users.service"); |
||||||
|
const typeorm_1 = require("@nestjs/typeorm"); |
||||||
|
const user_entity_1 = require("./user.entity"); |
||||||
|
let UsersModule = class UsersModule { |
||||||
|
}; |
||||||
|
exports.UsersModule = UsersModule; |
||||||
|
exports.UsersModule = UsersModule = __decorate([ |
||||||
|
(0, common_1.Module)({ |
||||||
|
imports: [typeorm_1.TypeOrmModule.forFeature([user_entity_1.User])], |
||||||
|
providers: [users_service_1.UsersService], |
||||||
|
controllers: [], |
||||||
|
exports: [users_service_1.UsersService] |
||||||
|
}) |
||||||
|
], UsersModule); |
||||||
|
//# sourceMappingURL=users.module.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"users.module.js","sourceRoot":"","sources":["../../src/users/users.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,mDAA+C;AAC/C,6CAAgD;AAChD,+CAAqC;AAQ9B,IAAM,WAAW,GAAjB,MAAM,WAAW;CAAG,CAAA;AAAd,kCAAW;sBAAX,WAAW;IANvB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,uBAAa,CAAC,UAAU,CAAC,CAAC,kBAAI,CAAC,CAAC,CAAC;QAC3C,SAAS,EAAE,CAAC,4BAAY,CAAC;QACzB,WAAW,EAAE,EAAE;QACf,OAAO,EAAE,CAAC,4BAAY,CAAC;KACxB,CAAC;GACW,WAAW,CAAG"} |
@ -0,0 +1,10 @@ |
|||||||
|
import { User } from './user.entity'; |
||||||
|
import { Repository } from 'typeorm'; |
||||||
|
import { CreateUserDto } from './dto/create-user.dto'; |
||||||
|
export declare class UsersService { |
||||||
|
private repo; |
||||||
|
constructor(repo: Repository<User>); |
||||||
|
findByName(name: string): Promise<User | null>; |
||||||
|
findByEmail(email: string): Promise<User | null>; |
||||||
|
create(dto: CreateUserDto): Promise<User>; |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
"use strict"; |
||||||
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { |
||||||
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); |
||||||
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
||||||
|
return c > 3 && r && Object.defineProperty(target, key, r), r; |
||||||
|
}; |
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) { |
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); |
||||||
|
}; |
||||||
|
var __param = (this && this.__param) || function (paramIndex, decorator) { |
||||||
|
return function (target, key) { decorator(target, key, paramIndex); } |
||||||
|
}; |
||||||
|
Object.defineProperty(exports, "__esModule", { value: true }); |
||||||
|
exports.UsersService = void 0; |
||||||
|
const common_1 = require("@nestjs/common"); |
||||||
|
const typeorm_1 = require("@nestjs/typeorm"); |
||||||
|
const user_entity_1 = require("./user.entity"); |
||||||
|
const typeorm_2 = require("typeorm"); |
||||||
|
let UsersService = class UsersService { |
||||||
|
repo; |
||||||
|
constructor(repo) { |
||||||
|
this.repo = repo; |
||||||
|
} |
||||||
|
async findByName(name) { |
||||||
|
return this.repo.findOne({ where: { name } }); |
||||||
|
} |
||||||
|
async findByEmail(email) { |
||||||
|
return this.repo.findOne({ where: { email } }); |
||||||
|
} |
||||||
|
async create(dto) { |
||||||
|
const existing = await this.findByName(dto.name); |
||||||
|
if (existing) |
||||||
|
throw new common_1.BadRequestException("Already Exist User"); |
||||||
|
const user = this.repo.create(dto); |
||||||
|
return this.repo.save(user); |
||||||
|
} |
||||||
|
}; |
||||||
|
exports.UsersService = UsersService; |
||||||
|
exports.UsersService = UsersService = __decorate([ |
||||||
|
(0, common_1.Injectable)(), |
||||||
|
__param(0, (0, typeorm_1.InjectRepository)(user_entity_1.User)), |
||||||
|
__metadata("design:paramtypes", [typeorm_2.Repository]) |
||||||
|
], UsersService); |
||||||
|
//# sourceMappingURL=users.service.js.map
|
@ -0,0 +1 @@ |
|||||||
|
{"version":3,"file":"users.service.js","sourceRoot":"","sources":["../../src/users/users.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAiE;AACjE,6CAAmD;AACnD,+CAAqC;AACrC,qCAAqC;AAI9B,IAAM,YAAY,GAAlB,MAAM,YAAY;IACuB;IAA5C,YAA4C,IAAsB;QAAtB,SAAI,GAAJ,IAAI,CAAkB;IAAG,CAAC;IAEtE,KAAK,CAAC,UAAU,CAAC,IAAY;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAC,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAC,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAkB;QAC3B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,QAAQ;YAAE,MAAM,IAAI,4BAAmB,CAAC,oBAAoB,CAAC,CAAC;QAElE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;CACJ,CAAA;AAlBY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;IAEI,WAAA,IAAA,0BAAgB,EAAC,kBAAI,CAAC,CAAA;qCAAe,oBAAU;GADnD,YAAY,CAkBxB"} |
@ -0,0 +1,34 @@ |
|||||||
|
// @ts-check
|
||||||
|
import eslint from '@eslint/js'; |
||||||
|
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; |
||||||
|
import globals from 'globals'; |
||||||
|
import tseslint from 'typescript-eslint'; |
||||||
|
|
||||||
|
export default tseslint.config( |
||||||
|
{ |
||||||
|
ignores: ['eslint.config.mjs'], |
||||||
|
}, |
||||||
|
eslint.configs.recommended, |
||||||
|
...tseslint.configs.recommendedTypeChecked, |
||||||
|
eslintPluginPrettierRecommended, |
||||||
|
{ |
||||||
|
languageOptions: { |
||||||
|
globals: { |
||||||
|
...globals.node, |
||||||
|
...globals.jest, |
||||||
|
}, |
||||||
|
sourceType: 'commonjs', |
||||||
|
parserOptions: { |
||||||
|
projectService: true, |
||||||
|
tsconfigRootDir: import.meta.dirname, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
rules: { |
||||||
|
'@typescript-eslint/no-explicit-any': 'off', |
||||||
|
'@typescript-eslint/no-floating-promises': 'warn', |
||||||
|
'@typescript-eslint/no-unsafe-argument': 'warn' |
||||||
|
}, |
||||||
|
}, |
||||||
|
); |
@ -0,0 +1,8 @@ |
|||||||
|
{ |
||||||
|
"$schema": "https://json.schemastore.org/nest-cli", |
||||||
|
"collection": "@nestjs/schematics", |
||||||
|
"sourceRoot": "src", |
||||||
|
"compilerOptions": { |
||||||
|
"deleteOutDir": true |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,85 @@ |
|||||||
|
{ |
||||||
|
"name": "backend", |
||||||
|
"version": "0.0.1", |
||||||
|
"description": "", |
||||||
|
"author": "", |
||||||
|
"private": true, |
||||||
|
"license": "UNLICENSED", |
||||||
|
"scripts": { |
||||||
|
"build": "nest build", |
||||||
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", |
||||||
|
"start": "nest start", |
||||||
|
"start:dev": "nest start --watch", |
||||||
|
"start:debug": "nest start --debug --watch", |
||||||
|
"start:prod": "node dist/main", |
||||||
|
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", |
||||||
|
"test": "jest", |
||||||
|
"test:watch": "jest --watch", |
||||||
|
"test:cov": "jest --coverage", |
||||||
|
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", |
||||||
|
"test:e2e": "jest --config ./test/jest-e2e.json" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"@nestjs/common": "^11.0.1", |
||||||
|
"@nestjs/config": "^4.0.2", |
||||||
|
"@nestjs/core": "^11.0.1", |
||||||
|
"@nestjs/jwt": "^11.0.0", |
||||||
|
"@nestjs/passport": "^11.0.5", |
||||||
|
"@nestjs/platform-express": "^11.0.1", |
||||||
|
"@nestjs/typeorm": "^11.0.0", |
||||||
|
"bcrypt": "^6.0.0", |
||||||
|
"class-transformer": "^0.5.1", |
||||||
|
"class-validator": "^0.14.2", |
||||||
|
"mysql2": "^3.14.2", |
||||||
|
"passport": "^0.7.0", |
||||||
|
"passport-jwt": "^4.0.1", |
||||||
|
"reflect-metadata": "^0.2.2", |
||||||
|
"rxjs": "^7.8.1", |
||||||
|
"typeorm": "^0.3.25" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@eslint/eslintrc": "^3.2.0", |
||||||
|
"@eslint/js": "^9.18.0", |
||||||
|
"@nestjs/cli": "^11.0.0", |
||||||
|
"@nestjs/schematics": "^11.0.0", |
||||||
|
"@nestjs/testing": "^11.0.1", |
||||||
|
"@swc/cli": "^0.6.0", |
||||||
|
"@swc/core": "^1.10.7", |
||||||
|
"@types/bcrypt": "^5.0.2", |
||||||
|
"@types/express": "^5.0.0", |
||||||
|
"@types/jest": "^29.5.14", |
||||||
|
"@types/node": "^22.10.7", |
||||||
|
"@types/supertest": "^6.0.2", |
||||||
|
"eslint": "^9.18.0", |
||||||
|
"eslint-config-prettier": "^10.0.1", |
||||||
|
"eslint-plugin-prettier": "^5.2.2", |
||||||
|
"globals": "^16.0.0", |
||||||
|
"jest": "^29.7.0", |
||||||
|
"prettier": "^3.4.2", |
||||||
|
"source-map-support": "^0.5.21", |
||||||
|
"supertest": "^7.0.0", |
||||||
|
"ts-jest": "^29.2.5", |
||||||
|
"ts-loader": "^9.5.2", |
||||||
|
"ts-node": "^10.9.2", |
||||||
|
"tsconfig-paths": "^4.2.0", |
||||||
|
"typescript": "^5.7.3", |
||||||
|
"typescript-eslint": "^8.20.0" |
||||||
|
}, |
||||||
|
"jest": { |
||||||
|
"moduleFileExtensions": [ |
||||||
|
"js", |
||||||
|
"json", |
||||||
|
"ts" |
||||||
|
], |
||||||
|
"rootDir": "src", |
||||||
|
"testRegex": ".*\\.spec\\.ts$", |
||||||
|
"transform": { |
||||||
|
"^.+\\.(t|j)s$": "ts-jest" |
||||||
|
}, |
||||||
|
"collectCoverageFrom": [ |
||||||
|
"**/*.(t|j)s" |
||||||
|
], |
||||||
|
"coverageDirectory": "../coverage", |
||||||
|
"testEnvironment": "node" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'; |
||||||
|
import { AppController } from './app.controller'; |
||||||
|
import { AppService } from './app.service'; |
||||||
|
|
||||||
|
describe('AppController', () => { |
||||||
|
let appController: AppController; |
||||||
|
|
||||||
|
beforeEach(async () => { |
||||||
|
const app: TestingModule = await Test.createTestingModule({ |
||||||
|
controllers: [AppController], |
||||||
|
providers: [AppService], |
||||||
|
}).compile(); |
||||||
|
|
||||||
|
appController = app.get<AppController>(AppController); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('root', () => { |
||||||
|
it('should return "Hello World!"', () => { |
||||||
|
expect(appController.getHello()).toBe('Hello World!'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,12 @@ |
|||||||
|
import { Controller, Get } from '@nestjs/common'; |
||||||
|
import { AppService } from './app.service'; |
||||||
|
|
||||||
|
@Controller() |
||||||
|
export class AppController { |
||||||
|
constructor(private readonly appService: AppService) {} |
||||||
|
|
||||||
|
@Get() |
||||||
|
getHello(): string { |
||||||
|
return this.appService.getHello(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
import { Module } from '@nestjs/common'; |
||||||
|
import { AppController } from './app.controller'; |
||||||
|
import { AppService } from './app.service'; |
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config'; |
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm'; |
||||||
|
import { join } from 'path'; |
||||||
|
import { AuthModule } from './auth/auth.module'; |
||||||
|
import { UsersModule } from './users/users.module'; |
||||||
|
import { JwtService } from '@nestjs/jwt'; |
||||||
|
|
||||||
|
@Module({ |
||||||
|
imports: [ |
||||||
|
ConfigModule.forRoot({ isGlobal: true }), // .env 불러오도록 설정
|
||||||
|
TypeOrmModule.forRootAsync({ |
||||||
|
imports: [ConfigModule], |
||||||
|
inject: [ConfigService], |
||||||
|
useFactory: async (config: ConfigService) => ({ |
||||||
|
type: 'mysql', |
||||||
|
host: config.get<string>('DB_HOST'), |
||||||
|
port: parseInt(config.get<string>('DB_PORT', '3306'), 10), |
||||||
|
username: config.get<string>('DB_USERNAME'), |
||||||
|
password: config.get<string>('DB_PASSWORD'), |
||||||
|
database: config.get<string>('DB_DATABASE'), |
||||||
|
entities: [join(__dirname, '**', '*.entity.{ts,js}')], |
||||||
|
synchronize: config.get<string>('NODE_ENV') !== 'production', // 개발 중에만 true
|
||||||
|
autoLoadEntities: true, |
||||||
|
logging: true, |
||||||
|
}), |
||||||
|
}), AuthModule, UsersModule |
||||||
|
], |
||||||
|
controllers: [AppController], |
||||||
|
providers: [AppService, JwtService], |
||||||
|
}) |
||||||
|
export class AppModule {} |
@ -0,0 +1,8 @@ |
|||||||
|
import { Injectable } from '@nestjs/common'; |
||||||
|
|
||||||
|
@Injectable() |
||||||
|
export class AppService { |
||||||
|
getHello(): string { |
||||||
|
return 'Hello World!'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'; |
||||||
|
import { AuthController } from './auth.controller'; |
||||||
|
|
||||||
|
describe('AuthController', () => { |
||||||
|
let controller: AuthController; |
||||||
|
|
||||||
|
beforeEach(async () => { |
||||||
|
const module: TestingModule = await Test.createTestingModule({ |
||||||
|
controllers: [AuthController], |
||||||
|
}).compile(); |
||||||
|
|
||||||
|
controller = module.get<AuthController>(AuthController); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should be defined', () => { |
||||||
|
expect(controller).toBeDefined(); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,19 @@ |
|||||||
|
import { Body, Controller, Post } from '@nestjs/common'; |
||||||
|
import { AuthService } from './auth.service'; |
||||||
|
import { CreateUserDto } from 'src/users/dto/create-user.dto'; |
||||||
|
import { LoginUserDto } from 'src/auth/dto/login-user.dto'; |
||||||
|
|
||||||
|
@Controller('auth') |
||||||
|
export class AuthController { |
||||||
|
constructor(private readonly authService: AuthService) {} |
||||||
|
|
||||||
|
@Post('signup') |
||||||
|
async signup(@Body() dto: CreateUserDto) { |
||||||
|
return this.authService.signup(dto); |
||||||
|
} |
||||||
|
|
||||||
|
@Post('login') |
||||||
|
async login(@Body() dto: LoginUserDto) { |
||||||
|
return this.authService.login(dto); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
import { Module } from '@nestjs/common'; |
||||||
|
import { AuthService } from './auth.service'; |
||||||
|
import { AuthController } from './auth.controller'; |
||||||
|
import { UsersModule } from 'src/users/users.module'; |
||||||
|
import { JwtModule } from '@nestjs/jwt'; |
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config'; |
||||||
|
import { PassportModule } from '@nestjs/passport'; |
||||||
|
|
||||||
|
@Module({ |
||||||
|
imports: [ |
||||||
|
UsersModule, |
||||||
|
PassportModule, |
||||||
|
ConfigModule, |
||||||
|
JwtModule.registerAsync({ |
||||||
|
imports: [ConfigModule], |
||||||
|
inject: [ConfigService], |
||||||
|
useFactory: async (configService: ConfigService) => ({ |
||||||
|
secret: configService.get<string>('JWT_SECRET'), |
||||||
|
signOptions: { |
||||||
|
expiresIn: configService.get<string>('JWT_EXPIRES_IN') || '60s', |
||||||
|
}, |
||||||
|
}) |
||||||
|
}) |
||||||
|
], |
||||||
|
providers: [AuthService], |
||||||
|
controllers: [AuthController] |
||||||
|
}) |
||||||
|
export class AuthModule {} |
@ -0,0 +1,18 @@ |
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'; |
||||||
|
import { AuthService } from './auth.service'; |
||||||
|
|
||||||
|
describe('AuthService', () => { |
||||||
|
let service: AuthService; |
||||||
|
|
||||||
|
beforeEach(async () => { |
||||||
|
const module: TestingModule = await Test.createTestingModule({ |
||||||
|
providers: [AuthService], |
||||||
|
}).compile(); |
||||||
|
|
||||||
|
service = module.get<AuthService>(AuthService); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should be defined', () => { |
||||||
|
expect(service).toBeDefined(); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,49 @@ |
|||||||
|
import { BadRequestException, Injectable, InternalServerErrorException, UnauthorizedException } from '@nestjs/common'; |
||||||
|
import { JwtService } from '@nestjs/jwt'; |
||||||
|
import { UsersService } from 'src/users/users.service'; |
||||||
|
import * as bcrypt from 'bcrypt' |
||||||
|
import { LoginUserDto } from 'src/auth/dto/login-user.dto'; |
||||||
|
import { CreateUserDto } from 'src/users/dto/create-user.dto'; |
||||||
|
|
||||||
|
@Injectable() |
||||||
|
export class AuthService { |
||||||
|
constructor(private userService: UsersService, private jwtService: JwtService) {} |
||||||
|
|
||||||
|
async validateUser(name: string, password: string): Promise<any> { |
||||||
|
const user = await this.userService.findByName(name); |
||||||
|
if (user && await bcrypt.compare(password, user.password)) { |
||||||
|
const { password, ...rest } = user; |
||||||
|
|
||||||
|
return rest; |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
async login(dto: LoginUserDto) { |
||||||
|
try { |
||||||
|
const user = await this.userService.findByName(dto.name); |
||||||
|
if (!user) throw new UnauthorizedException('Login failed'); |
||||||
|
|
||||||
|
const passwordCheck = await bcrypt.compare(dto.password, user.password); |
||||||
|
if (!passwordCheck) throw new UnauthorizedException('Login failed'); |
||||||
|
|
||||||
|
const payload = { username: user.name, sub: user.id }; |
||||||
|
return { access_token: this.jwtService.sign(payload) }; |
||||||
|
} catch (error) { |
||||||
|
if (error instanceof UnauthorizedException) throw error; |
||||||
|
|
||||||
|
throw new InternalServerErrorException('Login failed (Internal)'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async signup(dto: CreateUserDto) { |
||||||
|
try { |
||||||
|
const hashed = await bcrypt.hash(dto.password, 10); |
||||||
|
return this.userService.create({ ...dto, password: hashed }); |
||||||
|
} catch (error) { |
||||||
|
throw new BadRequestException('Signup failed'); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
import { IsString, MinLength } from "class-validator"; |
||||||
|
|
||||||
|
export class LoginUserDto { |
||||||
|
@IsString() |
||||||
|
readonly name: string; |
||||||
|
|
||||||
|
@IsString() |
||||||
|
@MinLength(4) |
||||||
|
readonly password: string; |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
import { CreateDateColumn, UpdateDateColumn } from "typeorm"; |
||||||
|
|
||||||
|
export abstract class TimestampedEntity { |
||||||
|
@CreateDateColumn({ type: 'timestamp' }) |
||||||
|
createdAt: Date; |
||||||
|
|
||||||
|
@UpdateDateColumn({ type: 'timestamp' }) |
||||||
|
updatedAt: Date; |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
import { NestFactory } from '@nestjs/core'; |
||||||
|
import { AppModule } from './app.module'; |
||||||
|
import { ValidationPipe } from '@nestjs/common'; |
||||||
|
|
||||||
|
async function bootstrap() { |
||||||
|
const app = await NestFactory.create(AppModule); |
||||||
|
app.enableCors(); |
||||||
|
app.useGlobalPipes( |
||||||
|
new ValidationPipe({ |
||||||
|
whitelist: true, // DTO 정의된 속성만 허용
|
||||||
|
forbidNonWhitelisted: true, // DTO 없는 속성 들어오면 에러
|
||||||
|
transform: true, // 자동 타입 변환
|
||||||
|
}) |
||||||
|
) |
||||||
|
await app.listen(process.env.PORT ?? 3000); |
||||||
|
} |
||||||
|
bootstrap(); |
@ -0,0 +1,14 @@ |
|||||||
|
import { IsEmail, IsOptional, IsString, MinLength } from "class-validator"; |
||||||
|
|
||||||
|
export class CreateUserDto { |
||||||
|
@IsString() |
||||||
|
readonly name: string; |
||||||
|
|
||||||
|
@IsOptional() |
||||||
|
@IsEmail() |
||||||
|
readonly email?: string; |
||||||
|
|
||||||
|
@IsString() |
||||||
|
@MinLength(4) |
||||||
|
readonly password: string; |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
import { TimestampedEntity } from "src/common/entities/timestamped.entity"; |
||||||
|
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; |
||||||
|
|
||||||
|
@Entity() |
||||||
|
export class User extends TimestampedEntity { |
||||||
|
@PrimaryGeneratedColumn() |
||||||
|
id: number; |
||||||
|
|
||||||
|
@Column({ unique: true }) |
||||||
|
name: string; |
||||||
|
|
||||||
|
@Column({ unique: true, nullable: true }) |
||||||
|
email?: string; |
||||||
|
|
||||||
|
@Column() |
||||||
|
password: string; |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
import { Module } from '@nestjs/common'; |
||||||
|
import { UsersService } from './users.service'; |
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm'; |
||||||
|
import { User } from './user.entity'; |
||||||
|
|
||||||
|
@Module({ |
||||||
|
imports: [TypeOrmModule.forFeature([User])], |
||||||
|
providers: [UsersService], |
||||||
|
controllers: [], |
||||||
|
exports: [UsersService] |
||||||
|
}) |
||||||
|
export class UsersModule {} |
@ -0,0 +1,18 @@ |
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'; |
||||||
|
import { UsersService } from './users.service'; |
||||||
|
|
||||||
|
describe('UsersService', () => { |
||||||
|
let service: UsersService; |
||||||
|
|
||||||
|
beforeEach(async () => { |
||||||
|
const module: TestingModule = await Test.createTestingModule({ |
||||||
|
providers: [UsersService], |
||||||
|
}).compile(); |
||||||
|
|
||||||
|
service = module.get<UsersService>(UsersService); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should be defined', () => { |
||||||
|
expect(service).toBeDefined(); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,26 @@ |
|||||||
|
import { BadRequestException, Injectable } from '@nestjs/common'; |
||||||
|
import { InjectRepository } from '@nestjs/typeorm'; |
||||||
|
import { User } from './user.entity'; |
||||||
|
import { Repository } from 'typeorm'; |
||||||
|
import { CreateUserDto } from './dto/create-user.dto'; |
||||||
|
|
||||||
|
@Injectable() |
||||||
|
export class UsersService { |
||||||
|
constructor(@InjectRepository(User) private repo: Repository<User>) {} |
||||||
|
|
||||||
|
async findByName(name: string): Promise<User | null> { |
||||||
|
return this.repo.findOne({ where: { name }}); |
||||||
|
} |
||||||
|
|
||||||
|
async findByEmail(email: string): Promise<User | null> { |
||||||
|
return this.repo.findOne({ where: { email }}); |
||||||
|
} |
||||||
|
|
||||||
|
async create(dto: CreateUserDto): Promise<User> { |
||||||
|
const existing = await this.findByName(dto.name); |
||||||
|
if (existing) throw new BadRequestException("Already Exist User"); |
||||||
|
|
||||||
|
const user = this.repo.create(dto); |
||||||
|
return this.repo.save(user); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'; |
||||||
|
import { INestApplication } from '@nestjs/common'; |
||||||
|
import * as request from 'supertest'; |
||||||
|
import { App } from 'supertest/types'; |
||||||
|
import { AppModule } from './../src/app.module'; |
||||||
|
|
||||||
|
describe('AppController (e2e)', () => { |
||||||
|
let app: INestApplication<App>; |
||||||
|
|
||||||
|
beforeEach(async () => { |
||||||
|
const moduleFixture: TestingModule = await Test.createTestingModule({ |
||||||
|
imports: [AppModule], |
||||||
|
}).compile(); |
||||||
|
|
||||||
|
app = moduleFixture.createNestApplication(); |
||||||
|
await app.init(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('/ (GET)', () => { |
||||||
|
return request(app.getHttpServer()) |
||||||
|
.get('/') |
||||||
|
.expect(200) |
||||||
|
.expect('Hello World!'); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,9 @@ |
|||||||
|
{ |
||||||
|
"moduleFileExtensions": ["js", "json", "ts"], |
||||||
|
"rootDir": ".", |
||||||
|
"testEnvironment": "node", |
||||||
|
"testRegex": ".e2e-spec.ts$", |
||||||
|
"transform": { |
||||||
|
"^.+\\.(t|j)s$": "ts-jest" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"extends": "./tsconfig.json", |
||||||
|
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"] |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
{ |
||||||
|
"compilerOptions": { |
||||||
|
"module": "commonjs", |
||||||
|
"declaration": true, |
||||||
|
"removeComments": true, |
||||||
|
"emitDecoratorMetadata": true, |
||||||
|
"experimentalDecorators": true, |
||||||
|
"allowSyntheticDefaultImports": true, |
||||||
|
"target": "ES2023", |
||||||
|
"sourceMap": true, |
||||||
|
"outDir": "./dist", |
||||||
|
"baseUrl": "./", |
||||||
|
"incremental": true, |
||||||
|
"skipLibCheck": true, |
||||||
|
"strictNullChecks": true, |
||||||
|
"forceConsistentCasingInFileNames": true, |
||||||
|
"noImplicitAny": false, |
||||||
|
"strictBindCallApply": false, |
||||||
|
"noFallthroughCasesInSwitch": false |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue