├── .env
├── .env.test
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── README.md
├── docker-compose.yml
├── nest-cli.json
├── package-lock.json
├── package.json
├── prisma
├── migrations
│ ├── 20230903131351_
│ │ └── migration.sql
│ ├── 20230904120642_
│ │ └── migration.sql
│ └── migration_lock.toml
└── schema.prisma
├── src
├── app.module.ts
├── auth
│ ├── auth.controller.ts
│ ├── auth.module.ts
│ ├── auth.service.ts
│ ├── decorator
│ │ └── request.decorator.ts
│ ├── dist
│ │ ├── auth.controller.js
│ │ ├── auth.module.js
│ │ ├── auth.service.js
│ │ └── dist
│ │ │ ├── auth.controller.dev.js
│ │ │ ├── auth.module.dev.js
│ │ │ └── auth.service.dev.js
│ ├── dto
│ │ ├── auth.dto.ts
│ │ ├── dist
│ │ │ ├── auth.dto.js
│ │ │ ├── dist
│ │ │ │ ├── auth.dto.dev.js
│ │ │ │ └── index.dev.js
│ │ │ └── index.js
│ │ └── index.ts
│ ├── guard
│ │ └── auth.guard.ts
│ └── strategy
│ │ ├── dist
│ │ ├── index.js
│ │ └── jwt.strategy.js
│ │ ├── index.ts
│ │ └── jwt.strategy.ts
├── bookmark
│ ├── bookmark.controller.ts
│ ├── bookmark.module.ts
│ └── bookmark.service.ts
├── main.ts
├── prisma
│ ├── prisma.module.ts
│ └── prisma.service.ts
└── user
│ ├── dto
│ ├── edit.user.ts
│ └── index.ts
│ ├── user.controller.ts
│ ├── user.module.ts
│ └── user.service.ts
├── test
├── app.e2e-spec.ts
└── jest-e2e.json
├── tsconfig.build.json
└── tsconfig.json
/.env:
--------------------------------------------------------------------------------
1 | # Environment variables declared in this file are automatically made available to Prisma.
2 | # See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
3 |
4 | # Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
5 | # See the documentation for all the connection string options: https://pris.ly/d/connection-strings
6 |
7 | DATABASE_URL="postgresql://postgres:sadra35289546@localhost:5434/nest?schema=public"
--------------------------------------------------------------------------------
/.env.test:
--------------------------------------------------------------------------------
1 | # Environment variables declared in this file are automatically made available to Prisma.
2 | # See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
3 |
4 | # Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
5 | # See the documentation for all the connection string options: https://pris.ly/d/connection-strings
6 |
7 | DATABASE_URL="postgresql://postgres:sadra35289546@localhost:5435/nest?schema=public"
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: '@typescript-eslint/parser',
3 | parserOptions: {
4 | project: 'tsconfig.json',
5 | tsconfigRootDir: __dirname,
6 | sourceType: 'module',
7 | },
8 | plugins: ['@typescript-eslint/eslint-plugin'],
9 | extends: [
10 | 'plugin:@typescript-eslint/recommended',
11 | 'plugin:prettier/recommended',
12 | ],
13 | root: true,
14 | env: {
15 | node: true,
16 | jest: true,
17 | },
18 | ignorePatterns: ['.eslintrc.js'],
19 | rules: {
20 | '@typescript-eslint/interface-name-prefix': 'off',
21 | '@typescript-eslint/explicit-function-return-type': 'off',
22 | '@typescript-eslint/explicit-module-boundary-types': 'off',
23 | '@typescript-eslint/no-explicit-any': 'off',
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # compiled output
2 | /dist
3 | /node_modules
4 |
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | pnpm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | lerna-debug.log*
13 |
14 | # OS
15 | .DS_Store
16 |
17 | # Tests
18 | /coverage
19 | /.nyc_output
20 |
21 | # IDEs and editors
22 | /.idea
23 | .project
24 | .classpath
25 | .c9/
26 | *.launch
27 | .settings/
28 | *.sublime-workspace
29 |
30 | # IDE - VSCode
31 | .vscode/*
32 | !.vscode/settings.json
33 | !.vscode/tasks.json
34 | !.vscode/launch.json
35 | !.vscode/extensions.json
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all"
4 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
6 | [circleci-url]: https://circleci.com/gh/nestjs/nest
7 |
8 | A progressive Node.js framework for building efficient and scalable server-side applications.
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
24 |
25 | ## Description
26 |
27 | [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
28 |
29 | ## Installation
30 |
31 | ```bash
32 | $ npm install
33 | ```
34 |
35 | ## Running the app
36 |
37 | ```bash
38 | # development
39 | $ npm run start
40 |
41 | # watch mode
42 | $ npm run start:dev
43 |
44 | # production mode
45 | $ npm run start:prod
46 | ```
47 |
48 | ## Test
49 |
50 | ```bash
51 | # unit tests
52 | $ npm run test
53 |
54 | # e2e tests
55 | $ npm run test:e2e
56 |
57 | # test coverage
58 | $ npm run test:cov
59 | ```
60 |
61 | ## Support
62 |
63 | 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).
64 |
65 | ## Stay in touch
66 |
67 | - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
68 | - Website - [https://nestjs.com](https://nestjs.com/)
69 | - Twitter - [@nestframework](https://twitter.com/nestframework)
70 |
71 | ## License
72 |
73 | Nest is [MIT licensed](LICENSE).
74 | # nest-restapi
75 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | dev-db:
4 | image: postgres:13
5 | ports:
6 | - 5434:5432
7 | environment:
8 | POSTGRES_USER: postgres
9 | POSTGRES_PASSWORD: sadra35289546
10 | POSTGRES_DB: nest
11 | test-db:
12 | image: postgres:13
13 | ports:
14 | - 5435:5432
15 | environment:
16 | POSTGRES_USER: postgres
17 | POSTGRES_PASSWORD: sadra35289546
18 | POSTGRES_DB: nest
19 |
--------------------------------------------------------------------------------
/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/nest-cli",
3 | "collection": "@nestjs/schematics",
4 | "sourceRoot": "src",
5 | "compilerOptions": {
6 | "deleteOutDir": true
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rest-api",
3 | "version": "0.0.1",
4 | "description": "",
5 | "author": "",
6 | "private": true,
7 | "license": "UNLICENSED",
8 | "scripts": {
9 | "prisma:dev:deploy": " prisma migrate deploy",
10 | "db:dev:up": "sudo docker compose up dev-db -d",
11 | "db:dev:rm": "sudo docker compose rm -s -f -v",
12 | "db:dev:restart": "npm run db:dev:rm && npm run db:dev:up && sleep 1 && run prisma:dev:deploy",
13 | "prisma:test:deploy": "dotenv -e .env.test -- prisma deploy",
14 | "db:test:up": "sudo docker compose up test-db -d",
15 | "db:test:rm": "sudo docker compose rm -s -f -v",
16 | "db:test:restart": "npm run db:test:rm && npm run db:test:up && sleep 1 && run prisma:test:deploy",
17 | "build": "nest build",
18 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
19 | "start": "nest start",
20 | "start:dev": "nest start --watch",
21 | "start:debug": "nest start --debug --watch",
22 | "start:prod": "node dist/main",
23 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
24 | "test": "jest",
25 | "test:watch": "jest --watch",
26 | "test:cov": "jest --coverage",
27 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
28 | "test:e2e": "dotenv -e .env.test -- jest --watch --no--cache --config ./test/jest-e2e.json"
29 | },
30 | "dependencies": {
31 | "@nestjs/common": "^10.0.0",
32 | "@nestjs/config": "^3.0.1",
33 | "@nestjs/core": "^10.0.0",
34 | "@nestjs/jwt": "^10.1.1",
35 | "@nestjs/passport": "^10.0.1",
36 | "@nestjs/platform-express": "^10.0.0",
37 | "@nestjs/swagger": "^7.1.10",
38 | "@prisma/client": "^5.2.0",
39 | "argon2": "^0.31.1",
40 | "class-transformer": "^0.5.1",
41 | "class-validator": "^0.14.0",
42 | "config": "^3.3.9",
43 | "dotenv-cli": "^7.3.0",
44 | "passport": "^0.6.0",
45 | "passport-jwt": "^4.0.1",
46 | "reflect-metadata": "^0.1.13",
47 | "rxjs": "^7.8.1"
48 | },
49 | "devDependencies": {
50 | "@nestjs/cli": "^10.0.0",
51 | "@nestjs/schematics": "^10.0.0",
52 | "@nestjs/testing": "^10.0.0",
53 | "@types/express": "^4.17.17",
54 | "@types/jest": "^29.5.2",
55 | "@types/node": "^20.3.1",
56 | "@types/passport-jwt": "^3.0.9",
57 | "@types/supertest": "^2.0.12",
58 | "@typescript-eslint/eslint-plugin": "^6.0.0",
59 | "@typescript-eslint/parser": "^6.0.0",
60 | "eslint": "^8.42.0",
61 | "eslint-config-prettier": "^9.0.0",
62 | "eslint-plugin-prettier": "^5.0.0",
63 | "jest": "^29.5.0",
64 | "nodemon": "^3.0.1",
65 | "prettier": "^3.0.0",
66 | "prisma": "^5.2.0",
67 | "source-map-support": "^0.5.21",
68 | "supertest": "^6.3.3",
69 | "ts-jest": "^29.1.0",
70 | "ts-loader": "^9.4.3",
71 | "ts-node": "^10.9.1",
72 | "tsconfig-paths": "^4.2.0",
73 | "typescript": "^5.1.3"
74 | },
75 | "jest": {
76 | "moduleFileExtensions": [
77 | "js",
78 | "json",
79 | "ts"
80 | ],
81 | "rootDir": "src",
82 | "testRegex": ".*\\.spec\\.ts$",
83 | "transform": {
84 | "^.+\\.(t|j)s$": "ts-jest"
85 | },
86 | "collectCoverageFrom": [
87 | "**/*.(t|j)s"
88 | ],
89 | "coverageDirectory": "../coverage",
90 | "testEnvironment": "node"
91 | }
92 | }
--------------------------------------------------------------------------------
/prisma/migrations/20230903131351_/migration.sql:
--------------------------------------------------------------------------------
1 | -- CreateTable
2 | CREATE TABLE "User" (
3 | "id" SERIAL NOT NULL,
4 | "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
5 | "updatedAt" TIMESTAMP(3) NOT NULL,
6 | "email" TEXT NOT NULL,
7 | "password" TEXT NOT NULL,
8 | "first_name" TEXT,
9 | "last_name" TEXT,
10 |
11 | CONSTRAINT "User_pkey" PRIMARY KEY ("id")
12 | );
13 |
14 | -- CreateTable
15 | CREATE TABLE "Bookmark" (
16 | "id" SERIAL NOT NULL,
17 | "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
18 | "updatedAt" TIMESTAMP(3) NOT NULL,
19 | "title" TEXT NOT NULL,
20 | "description" TEXT NOT NULL,
21 | "link" TEXT NOT NULL,
22 |
23 | CONSTRAINT "Bookmark_pkey" PRIMARY KEY ("id")
24 | );
25 |
--------------------------------------------------------------------------------
/prisma/migrations/20230904120642_/migration.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Warnings:
3 |
4 | - A unique constraint covering the columns `[id]` on the table `Bookmark` will be added. If there are existing duplicate values, this will fail.
5 | - A unique constraint covering the columns `[id]` on the table `User` will be added. If there are existing duplicate values, this will fail.
6 | - A unique constraint covering the columns `[email]` on the table `User` will be added. If there are existing duplicate values, this will fail.
7 | - Added the required column `userID` to the `Bookmark` table without a default value. This is not possible if the table is not empty.
8 |
9 | */
10 | -- AlterTable
11 | ALTER TABLE "Bookmark" ADD COLUMN "userID" INTEGER NOT NULL;
12 |
13 | -- CreateIndex
14 | CREATE UNIQUE INDEX "Bookmark_id_key" ON "Bookmark"("id");
15 |
16 | -- CreateIndex
17 | CREATE UNIQUE INDEX "User_id_key" ON "User"("id");
18 |
19 | -- CreateIndex
20 | CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
21 |
22 | -- AddForeignKey
23 | ALTER TABLE "Bookmark" ADD CONSTRAINT "Bookmark_userID_fkey" FOREIGN KEY ("userID") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
24 |
--------------------------------------------------------------------------------
/prisma/migrations/migration_lock.toml:
--------------------------------------------------------------------------------
1 | # Please do not edit this file manually
2 | # It should be added in your version-control system (i.e. Git)
3 | provider = "postgresql"
--------------------------------------------------------------------------------
/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | // This is your Prisma schema file,
2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema
3 |
4 | generator client {
5 | provider = "prisma-client-js"
6 | }
7 |
8 | datasource db {
9 | provider = "postgresql"
10 | url = env("DATABASE_URL")
11 | }
12 |
13 | model User {
14 | id Int @id @unique @default(autoincrement())
15 | createdAt DateTime @default(now())
16 | updatedAt DateTime @updatedAt
17 | email String @unique
18 | password String
19 | first_name String?
20 | last_name String?
21 | Bookmark Bookmark[]
22 | }
23 |
24 | model Bookmark {
25 | id Int @id @unique @default(autoincrement())
26 | createdAt DateTime @default(now())
27 | updatedAt DateTime @updatedAt
28 | title String
29 | description String
30 | link String
31 | userID Int
32 | userDetail User @relation(fields: [userID], references: [id])
33 | }
34 |
--------------------------------------------------------------------------------
/src/app.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { AuthModule } from './auth/auth.module';
3 | import { UserModule } from './user/user.module';
4 | import { BookmarkModule } from './bookmark/bookmark.module';
5 | import { PrismaModule } from './prisma/prisma.module';
6 | import { ConfigModule } from '@nestjs/config';
7 |
8 | @Module({
9 | imports: [
10 | ConfigModule.forRoot({ isGlobal: true }),
11 | AuthModule,
12 | UserModule,
13 | BookmarkModule,
14 | PrismaModule],
15 | })
16 | export class AppModule { }
17 |
--------------------------------------------------------------------------------
/src/auth/auth.controller.ts:
--------------------------------------------------------------------------------
1 | import { Body, Controller, HttpCode, Post } from "@nestjs/common";
2 | import { AuthService } from "./auth.service";
3 | import { AuthDto } from "./dto";
4 | import { singinDecorator, singupDecorator } from './decorator/request.decorator';
5 |
6 | @Controller('auth')
7 | export class AuthController {
8 | constructor(private authservice: AuthService) { }
9 |
10 | @singinDecorator()
11 | signup(@Body() dto: AuthDto) {
12 | return this.authservice.signin(dto);
13 | }
14 |
15 | @singupDecorator()
16 | signin(@Body() dto: AuthDto) {
17 | return this.authservice.signup(dto);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/auth/auth.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from "@nestjs/common";
2 | import { AuthController } from "./auth.controller";
3 | import { AuthService } from "./auth.service";
4 | import { JwtModule } from "@nestjs/jwt";
5 | import { JwtStrategy } from './strategy';
6 |
7 | @Module({
8 | imports: [JwtModule.register({ secret: "secret_key" })],
9 | controllers: [AuthController],
10 | providers: [AuthService, JwtStrategy]
11 | })
12 | export class AuthModule {
13 |
14 | }
--------------------------------------------------------------------------------
/src/auth/auth.service.ts:
--------------------------------------------------------------------------------
1 | import { ForbiddenException, Injectable, NotFoundException } from "@nestjs/common";
2 | import { PrismaService } from "../prisma/prisma.service";
3 | import { AuthDto } from "./dto";
4 | import * as argon from "argon2"
5 | import { PrismaClientKnownRequestError, } from "@prisma/client/runtime/library";
6 | import { JwtService } from "@nestjs/jwt";
7 | @Injectable({})
8 |
9 | export class AuthService {
10 | constructor(private prisma: PrismaService, private jwt: JwtService) { }
11 | async signin(dto: AuthDto): Promise<{ msg: string }> {
12 | try {
13 | const hashPassword = await argon.hash(dto.password);
14 | const userData = {
15 | email: dto.email,
16 | password: hashPassword
17 | }
18 | await this.prisma.user.create({ data: userData });
19 | return { msg: "user created successfully" };
20 | } catch (error) {
21 | if (error instanceof PrismaClientKnownRequestError)
22 | if (error.code == "P2002") {
23 | throw new ForbiddenException("email has been already registered")
24 | }
25 | throw error
26 | }
27 | }
28 | async signup(dto: AuthDto): Promise {
29 | const user = await this.prisma.user.findFirst({ where: { email: dto.email } });
30 | if (!user) throw new NotFoundException({ msg: "user not found" });
31 | const pwCompare = await argon.verify(user.password, dto.password);
32 | if (!pwCompare) throw new ForbiddenException("email or password is invalid");
33 | return this.singToken(user.id, user.email);
34 | }
35 | async singToken(userId: number, userEmail: string) {
36 | const payload = {
37 | sub: userId,
38 | email: userEmail
39 | };
40 | const token = await this.jwt.signAsync(payload, {
41 | expiresIn: "1h"
42 | });
43 | return token
44 | }
45 | }
--------------------------------------------------------------------------------
/src/auth/decorator/request.decorator.ts:
--------------------------------------------------------------------------------
1 | import { ExecutionContext, HttpCode, Post, applyDecorators, createParamDecorator, Request } from '@nestjs/common';
2 | import { ApiResponse, ApiTags } from "@nestjs/swagger"
3 |
4 | export function singinDecorator() {
5 | return applyDecorators(
6 | ApiTags("auth"),
7 | ApiResponse({ status: 201, description: "user created successfully" }),
8 | ApiResponse({ status: 403, description: "internal server error" }),
9 | Post('signup'),
10 | HttpCode(201),
11 | )
12 | }
13 | export function singupDecorator() {
14 | return applyDecorators(
15 | ApiTags("auth"),
16 | ApiResponse({ status: 201, description: "user created successfully" }),
17 | ApiResponse({ status: 403, description: "internal server error" }),
18 | Post('signin'),
19 | HttpCode(200)
20 | )
21 | }
22 | export const GetUser = createParamDecorator(
23 | (
24 | data: string | undefined,
25 | ctx: ExecutionContext
26 | ) => {
27 | const request: Express.Request = ctx.switchToHttp().getRequest();
28 | if (data) {
29 | return request.user[data];
30 | }
31 | return request.user;
32 |
33 | })
--------------------------------------------------------------------------------
/src/auth/dist/auth.controller.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5 | 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;
6 | return c > 3 && r && Object.defineProperty(target, key, r), r;
7 | };
8 | var __param = (this && this.__param) || function (paramIndex, decorator) {
9 | return function (target, key) { decorator(target, key, paramIndex); }
10 | };
11 | exports.__esModule = true;
12 | exports.AuthController = void 0;
13 | var common_1 = require("@nestjs/common");
14 | var swagger_1 = require("@nestjs/swagger");
15 | var AuthController = /** @class */ (function () {
16 | function AuthController(authservice) {
17 | this.authservice = authservice;
18 | }
19 | AuthController.prototype.signup = function (dto) {
20 | return this.authservice.signin(dto);
21 | };
22 | AuthController.prototype.signin = function (dto) {
23 | return this.authservice.signup(dto);
24 | };
25 | __decorate([
26 | swagger_1.ApiTags("auth"),
27 | swagger_1.ApiResponse({ status: 201, description: "user created successfully" }),
28 | swagger_1.ApiResponse({ status: 403, description: "internal server error" }),
29 | common_1.Post('signup'),
30 | common_1.HttpCode(201),
31 | __param(0, common_1.Body())
32 | ], AuthController.prototype, "signup");
33 | __decorate([
34 | common_1.Post('signin'),
35 | common_1.HttpCode(200),
36 | __param(0, common_1.Body())
37 | ], AuthController.prototype, "signin");
38 | AuthController = __decorate([
39 | common_1.Controller('auth')
40 | ], AuthController);
41 | return AuthController;
42 | }());
43 | exports.AuthController = AuthController;
44 |
--------------------------------------------------------------------------------
/src/auth/dist/auth.module.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5 | 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;
6 | return c > 3 && r && Object.defineProperty(target, key, r), r;
7 | };
8 | exports.__esModule = true;
9 | exports.AuthModule = void 0;
10 | var common_1 = require("@nestjs/common");
11 | var auth_controller_1 = require("./auth.controller");
12 | var auth_service_1 = require("./auth.service");
13 | var jwt_1 = require("@nestjs/jwt");
14 | var strategy_1 = require("./strategy");
15 | var AuthModule = /** @class */ (function () {
16 | function AuthModule() {
17 | }
18 | AuthModule = __decorate([
19 | common_1.Module({
20 | imports: [jwt_1.JwtModule.register({ secret: "secret_key" })],
21 | controllers: [auth_controller_1.AuthController],
22 | providers: [auth_service_1.AuthService, strategy_1.JwtStrategy]
23 | })
24 | ], AuthModule);
25 | return AuthModule;
26 | }());
27 | exports.AuthModule = AuthModule;
28 |
--------------------------------------------------------------------------------
/src/auth/dist/auth.service.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5 | 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;
6 | return c > 3 && r && Object.defineProperty(target, key, r), r;
7 | };
8 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10 | return new (P || (P = Promise))(function (resolve, reject) {
11 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14 | step((generator = generator.apply(thisArg, _arguments || [])).next());
15 | });
16 | };
17 | var __generator = (this && this.__generator) || function (thisArg, body) {
18 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
19 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
20 | function verb(n) { return function (v) { return step([n, v]); }; }
21 | function step(op) {
22 | if (f) throw new TypeError("Generator is already executing.");
23 | while (_) try {
24 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
25 | if (y = 0, t) op = [op[0] & 2, t.value];
26 | switch (op[0]) {
27 | case 0: case 1: t = op; break;
28 | case 4: _.label++; return { value: op[1], done: false };
29 | case 5: _.label++; y = op[1]; op = [0]; continue;
30 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
31 | default:
32 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
33 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
34 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
35 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
36 | if (t[2]) _.ops.pop();
37 | _.trys.pop(); continue;
38 | }
39 | op = body.call(thisArg, _);
40 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
41 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
42 | }
43 | };
44 | exports.__esModule = true;
45 | exports.AuthService = void 0;
46 | var common_1 = require("@nestjs/common");
47 | var argon = require("argon2");
48 | var library_1 = require("@prisma/client/runtime/library");
49 | var AuthService = /** @class */ (function () {
50 | function AuthService(prisma, jwt) {
51 | this.prisma = prisma;
52 | this.jwt = jwt;
53 | }
54 | AuthService.prototype.signin = function (dto) {
55 | return __awaiter(this, void 0, Promise, function () {
56 | var hashPassword, userData, error_1;
57 | return __generator(this, function (_a) {
58 | switch (_a.label) {
59 | case 0:
60 | _a.trys.push([0, 3, , 4]);
61 | return [4 /*yield*/, argon.hash(dto.password)];
62 | case 1:
63 | hashPassword = _a.sent();
64 | userData = {
65 | email: dto.email,
66 | password: hashPassword
67 | };
68 | return [4 /*yield*/, this.prisma.user.create({ data: userData })];
69 | case 2:
70 | _a.sent();
71 | return [2 /*return*/, { msg: "user created successfully" }];
72 | case 3:
73 | error_1 = _a.sent();
74 | if (error_1 instanceof library_1.PrismaClientKnownRequestError)
75 | if (error_1.code == "P2002") {
76 | throw new common_1.ForbiddenException("email has been already registered");
77 | }
78 | throw error_1;
79 | case 4: return [2 /*return*/];
80 | }
81 | });
82 | });
83 | };
84 | AuthService.prototype.signup = function (dto) {
85 | return __awaiter(this, void 0, Promise, function () {
86 | var user, pwCompare;
87 | return __generator(this, function (_a) {
88 | switch (_a.label) {
89 | case 0: return [4 /*yield*/, this.prisma.user.findFirst({ where: { email: dto.email } })];
90 | case 1:
91 | user = _a.sent();
92 | if (!user)
93 | throw new common_1.NotFoundException({ msg: "user not found" });
94 | return [4 /*yield*/, argon.verify(user.password, dto.password)];
95 | case 2:
96 | pwCompare = _a.sent();
97 | if (!pwCompare)
98 | throw new common_1.ForbiddenException("email or password is invalid");
99 | return [2 /*return*/, this.singToken(user.id, user.email)];
100 | }
101 | });
102 | });
103 | };
104 | AuthService.prototype.singToken = function (userId, userEmail) {
105 | return __awaiter(this, void 0, void 0, function () {
106 | var payload, token;
107 | return __generator(this, function (_a) {
108 | switch (_a.label) {
109 | case 0:
110 | payload = {
111 | sub: userId,
112 | username: userEmail
113 | };
114 | return [4 /*yield*/, this.jwt.signAsync(payload, {
115 | secret: "secret",
116 | expiresIn: "1h"
117 | })];
118 | case 1:
119 | token = _a.sent();
120 | return [2 /*return*/, token];
121 | }
122 | });
123 | });
124 | };
125 | AuthService = __decorate([
126 | common_1.Injectable({})
127 | ], AuthService);
128 | return AuthService;
129 | }());
130 | exports.AuthService = AuthService;
131 |
--------------------------------------------------------------------------------
/src/auth/dist/dist/auth.controller.dev.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4 |
5 | var __decorate = void 0 && (void 0).__decorate || function (decorators, target, key, desc) {
6 | var c = arguments.length,
7 | r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
8 | d;
9 | if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) {
10 | if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
11 | }
12 | return c > 3 && r && Object.defineProperty(target, key, r), r;
13 | };
14 |
15 | var __param = void 0 && (void 0).__param || function (paramIndex, decorator) {
16 | return function (target, key) {
17 | decorator(target, key, paramIndex);
18 | };
19 | };
20 |
21 | exports.__esModule = true;
22 | exports.AuthController = void 0;
23 |
24 | var common_1 = require("@nestjs/common");
25 |
26 | var AuthController =
27 | /** @class */
28 | function () {
29 | function AuthController(authservice) {
30 | this.authservice = authservice;
31 | }
32 |
33 | AuthController.prototype.signup = function (dto) {
34 | return this.authservice.signin(dto);
35 | };
36 |
37 | AuthController.prototype.signin = function (dto) {
38 | return this.authservice.signup(dto);
39 | };
40 |
41 | __decorate([common_1.Post('signup'), common_1.HttpCode(201), __param(0, common_1.Body())], AuthController.prototype, "signup");
42 |
43 | __decorate([common_1.Post('signin'), common_1.HttpCode(200), __param(0, common_1.Body())], AuthController.prototype, "signin");
44 |
45 | AuthController = __decorate([common_1.Controller('auth')], AuthController);
46 | return AuthController;
47 | }();
48 |
49 | exports.AuthController = AuthController;
--------------------------------------------------------------------------------
/src/auth/dist/dist/auth.module.dev.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4 |
5 | var __decorate = void 0 && (void 0).__decorate || function (decorators, target, key, desc) {
6 | var c = arguments.length,
7 | r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
8 | d;
9 | if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) {
10 | if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
11 | }
12 | return c > 3 && r && Object.defineProperty(target, key, r), r;
13 | };
14 |
15 | exports.__esModule = true;
16 | exports.AuthModule = void 0;
17 |
18 | var common_1 = require("@nestjs/common");
19 |
20 | var auth_controller_1 = require("./auth.controller");
21 |
22 | var auth_service_1 = require("./auth.service");
23 |
24 | var jwt_1 = require("@nestjs/jwt");
25 |
26 | var AuthModule =
27 | /** @class */
28 | function () {
29 | function AuthModule() {}
30 |
31 | AuthModule = __decorate([common_1.Module({
32 | controllers: [auth_controller_1.AuthController],
33 | providers: [auth_service_1.AuthService],
34 | exports: [jwt_1.JwtModule.register({
35 | secret: "secret_key"
36 | })]
37 | })], AuthModule);
38 | return AuthModule;
39 | }();
40 |
41 | exports.AuthModule = AuthModule;
--------------------------------------------------------------------------------
/src/auth/dist/dist/auth.service.dev.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4 |
5 | var __decorate = void 0 && (void 0).__decorate || function (decorators, target, key, desc) {
6 | var c = arguments.length,
7 | r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
8 | d;
9 | if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) {
10 | if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
11 | }
12 | return c > 3 && r && Object.defineProperty(target, key, r), r;
13 | };
14 |
15 | var __awaiter = void 0 && (void 0).__awaiter || function (thisArg, _arguments, P, generator) {
16 | function adopt(value) {
17 | return value instanceof P ? value : new P(function (resolve) {
18 | resolve(value);
19 | });
20 | }
21 |
22 | return new (P || (P = Promise))(function (resolve, reject) {
23 | function fulfilled(value) {
24 | try {
25 | step(generator.next(value));
26 | } catch (e) {
27 | reject(e);
28 | }
29 | }
30 |
31 | function rejected(value) {
32 | try {
33 | step(generator["throw"](value));
34 | } catch (e) {
35 | reject(e);
36 | }
37 | }
38 |
39 | function step(result) {
40 | result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
41 | }
42 |
43 | step((generator = generator.apply(thisArg, _arguments || [])).next());
44 | });
45 | };
46 |
47 | var __generator = void 0 && (void 0).__generator || function (thisArg, body) {
48 | var _ = {
49 | label: 0,
50 | sent: function sent() {
51 | if (t[0] & 1) throw t[1];
52 | return t[1];
53 | },
54 | trys: [],
55 | ops: []
56 | },
57 | f,
58 | y,
59 | t,
60 | g;
61 | return g = {
62 | next: verb(0),
63 | "throw": verb(1),
64 | "return": verb(2)
65 | }, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
66 | return this;
67 | }), g;
68 |
69 | function verb(n) {
70 | return function (v) {
71 | return step([n, v]);
72 | };
73 | }
74 |
75 | function step(op) {
76 | if (f) throw new TypeError("Generator is already executing.");
77 |
78 | while (_) {
79 | try {
80 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
81 | if (y = 0, t) op = [op[0] & 2, t.value];
82 |
83 | switch (op[0]) {
84 | case 0:
85 | case 1:
86 | t = op;
87 | break;
88 |
89 | case 4:
90 | _.label++;
91 | return {
92 | value: op[1],
93 | done: false
94 | };
95 |
96 | case 5:
97 | _.label++;
98 | y = op[1];
99 | op = [0];
100 | continue;
101 |
102 | case 7:
103 | op = _.ops.pop();
104 |
105 | _.trys.pop();
106 |
107 | continue;
108 |
109 | default:
110 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
111 | _ = 0;
112 | continue;
113 | }
114 |
115 | if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
116 | _.label = op[1];
117 | break;
118 | }
119 |
120 | if (op[0] === 6 && _.label < t[1]) {
121 | _.label = t[1];
122 | t = op;
123 | break;
124 | }
125 |
126 | if (t && _.label < t[2]) {
127 | _.label = t[2];
128 |
129 | _.ops.push(op);
130 |
131 | break;
132 | }
133 |
134 | if (t[2]) _.ops.pop();
135 |
136 | _.trys.pop();
137 |
138 | continue;
139 | }
140 |
141 | op = body.call(thisArg, _);
142 | } catch (e) {
143 | op = [6, e];
144 | y = 0;
145 | } finally {
146 | f = t = 0;
147 | }
148 | }
149 |
150 | if (op[0] & 5) throw op[1];
151 | return {
152 | value: op[0] ? op[1] : void 0,
153 | done: true
154 | };
155 | }
156 | };
157 |
158 | exports.__esModule = true;
159 | exports.AuthService = void 0;
160 |
161 | var common_1 = require("@nestjs/common");
162 |
163 | var argon = require("argon2");
164 |
165 | var library_1 = require("@prisma/client/runtime/library");
166 |
167 | var AuthService =
168 | /** @class */
169 | function () {
170 | function AuthService(prisma, jwt) {
171 | this.prisma = prisma;
172 | this.jwt = jwt;
173 | }
174 |
175 | AuthService.prototype.signin = function (dto) {
176 | return __awaiter(this, void 0, Promise, function () {
177 | var hashPassword, userData, error_1;
178 | return __generator(this, function (_a) {
179 | switch (_a.label) {
180 | case 0:
181 | _a.trys.push([0, 3,, 4]);
182 |
183 | return [4
184 | /*yield*/
185 | , argon.hash(dto.password)];
186 |
187 | case 1:
188 | hashPassword = _a.sent();
189 | userData = {
190 | email: dto.email,
191 | password: hashPassword
192 | };
193 | return [4
194 | /*yield*/
195 | , this.prisma.user.create({
196 | data: userData
197 | })];
198 |
199 | case 2:
200 | _a.sent();
201 |
202 | return [2
203 | /*return*/
204 | , {
205 | msg: "user created successfully"
206 | }];
207 |
208 | case 3:
209 | error_1 = _a.sent();
210 | if (error_1 instanceof library_1.PrismaClientKnownRequestError) if (error_1.code == "P2002") {
211 | throw new common_1.ForbiddenException("email has been already registered");
212 | }
213 | throw error_1;
214 |
215 | case 4:
216 | return [2
217 | /*return*/
218 | ];
219 | }
220 | });
221 | });
222 | };
223 |
224 | AuthService.prototype.signup = function (dto) {
225 | return __awaiter(this, void 0, Promise, function () {
226 | var user, pwCompare;
227 | return __generator(this, function (_a) {
228 | switch (_a.label) {
229 | case 0:
230 | return [4
231 | /*yield*/
232 | , this.prisma.user.findFirst({
233 | where: {
234 | email: dto.email
235 | }
236 | })];
237 |
238 | case 1:
239 | user = _a.sent();
240 | if (!user) throw new common_1.NotFoundException({
241 | msg: "user not found"
242 | });
243 | return [4
244 | /*yield*/
245 | , argon.verify(user.password, dto.password)];
246 |
247 | case 2:
248 | pwCompare = _a.sent();
249 | if (!pwCompare) throw new common_1.ForbiddenException("email or password is invalid");
250 | return [2
251 | /*return*/
252 | , this.singToken(user.id, user.email)];
253 | }
254 | });
255 | });
256 | };
257 |
258 | AuthService.prototype.singToken = function (userId, userEmail) {
259 | return __awaiter(this, void 0, void 0, function () {
260 | var payload, token;
261 | return __generator(this, function (_a) {
262 | switch (_a.label) {
263 | case 0:
264 | payload = {
265 | sub: userId,
266 | username: userEmail
267 | };
268 | return [4
269 | /*yield*/
270 | , this.jwt.signAsync(payload, {
271 | secret: "secret",
272 | expiresIn: "1h"
273 | })];
274 |
275 | case 1:
276 | token = _a.sent();
277 | return [2
278 | /*return*/
279 | , token];
280 | }
281 | });
282 | });
283 | };
284 |
285 | AuthService = __decorate([common_1.Injectable({})], AuthService);
286 | return AuthService;
287 | }();
288 |
289 | exports.AuthService = AuthService;
--------------------------------------------------------------------------------
/src/auth/dto/auth.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from "@nestjs/swagger";
2 | import { IsEmail, IsNotEmpty, IsString } from "class-validator";
3 |
4 | export class AuthDto {
5 | @ApiProperty({ example: "email@email.com" })
6 | @IsNotEmpty()
7 | @IsEmail()
8 | email: string;
9 |
10 | @ApiProperty({ example: "myPassword" })
11 | @IsString()
12 | @IsNotEmpty()
13 | password: string
14 |
15 | }
--------------------------------------------------------------------------------
/src/auth/dto/dist/auth.dto.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5 | 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;
6 | return c > 3 && r && Object.defineProperty(target, key, r), r;
7 | };
8 | exports.__esModule = true;
9 | exports.AuthDto = void 0;
10 | var swagger_1 = require("@nestjs/swagger");
11 | var class_validator_1 = require("class-validator");
12 | var AuthDto = /** @class */ (function () {
13 | function AuthDto() {
14 | }
15 | __decorate([
16 | swagger_1.ApiProperty({ example: "email@email.com" }),
17 | class_validator_1.IsNotEmpty(),
18 | class_validator_1.IsEmail()
19 | ], AuthDto.prototype, "email");
20 | __decorate([
21 | swagger_1.ApiProperty({ example: "myPassword" }),
22 | class_validator_1.IsString(),
23 | class_validator_1.IsNotEmpty()
24 | ], AuthDto.prototype, "password");
25 | return AuthDto;
26 | }());
27 | exports.AuthDto = AuthDto;
28 |
--------------------------------------------------------------------------------
/src/auth/dto/dist/dist/auth.dto.dev.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4 |
5 | var __decorate = void 0 && (void 0).__decorate || function (decorators, target, key, desc) {
6 | var c = arguments.length,
7 | r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
8 | d;
9 | if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) {
10 | if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
11 | }
12 | return c > 3 && r && Object.defineProperty(target, key, r), r;
13 | };
14 |
15 | exports.__esModule = true;
16 | exports.AuthDto = void 0;
17 |
18 | var class_validator_1 = require("class-validator");
19 |
20 | var AuthDto =
21 | /** @class */
22 | function () {
23 | function AuthDto() {}
24 |
25 | __decorate([class_validator_1.IsNotEmpty(), class_validator_1.IsEmail()], AuthDto.prototype, "email");
26 |
27 | __decorate([class_validator_1.IsString(), class_validator_1.IsNotEmpty()], AuthDto.prototype, "password");
28 |
29 | return AuthDto;
30 | }();
31 |
32 | exports.AuthDto = AuthDto;
--------------------------------------------------------------------------------
/src/auth/dto/dist/dist/index.dev.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) {
4 | if (k2 === undefined) k2 = k;
5 | Object.defineProperty(o, k2, {
6 | enumerable: true,
7 | get: function get() {
8 | return m[k];
9 | }
10 | });
11 | } : function (o, m, k, k2) {
12 | if (k2 === undefined) k2 = k;
13 | o[k2] = m[k];
14 | });
15 |
16 | var __exportStar = void 0 && (void 0).__exportStar || function (m, exports) {
17 | for (var p in m) {
18 | if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
19 | }
20 | };
21 |
22 | exports.__esModule = true;
23 |
24 | __exportStar(require("./auth.dto"), exports);
--------------------------------------------------------------------------------
/src/auth/dto/dist/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5 | }) : (function(o, m, k, k2) {
6 | if (k2 === undefined) k2 = k;
7 | o[k2] = m[k];
8 | }));
9 | var __exportStar = (this && this.__exportStar) || function(m, exports) {
10 | for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
11 | };
12 | exports.__esModule = true;
13 | __exportStar(require("./auth.dto"), exports);
14 |
--------------------------------------------------------------------------------
/src/auth/dto/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./auth.dto"
--------------------------------------------------------------------------------
/src/auth/guard/auth.guard.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Injectable,
3 | } from '@nestjs/common';
4 | import { AuthGuard } from '@nestjs/passport';
5 |
6 |
7 | @Injectable()
8 | export class JwtGuard extends AuthGuard('jwt') {
9 | constructor() {
10 | super();
11 | }
12 | }
--------------------------------------------------------------------------------
/src/auth/strategy/dist/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5 | }) : (function(o, m, k, k2) {
6 | if (k2 === undefined) k2 = k;
7 | o[k2] = m[k];
8 | }));
9 | var __exportStar = (this && this.__exportStar) || function(m, exports) {
10 | for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
11 | };
12 | exports.__esModule = true;
13 | __exportStar(require("./jwt.strategy"), exports);
14 |
--------------------------------------------------------------------------------
/src/auth/strategy/dist/jwt.strategy.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __extends = (this && this.__extends) || (function () {
3 | var extendStatics = function (d, b) {
4 | extendStatics = Object.setPrototypeOf ||
5 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7 | return extendStatics(d, b);
8 | };
9 | return function (d, b) {
10 | extendStatics(d, b);
11 | function __() { this.constructor = d; }
12 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13 | };
14 | })();
15 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
16 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
17 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
18 | 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;
19 | return c > 3 && r && Object.defineProperty(target, key, r), r;
20 | };
21 | exports.__esModule = true;
22 | exports.JwtStrategy = void 0;
23 | var common_1 = require("@nestjs/common");
24 | var passport_1 = require("@nestjs/passport");
25 | var passport_jwt_1 = require("passport-jwt");
26 | var JwtStrategy = /** @class */ (function (_super) {
27 | __extends(JwtStrategy, _super);
28 | function JwtStrategy() {
29 | return _super.call(this, {
30 | jwtFromRequest: passport_jwt_1.ExtractJwt.fromAuthHeaderAsBearerToken(),
31 | secretOrKey: 'JWT_SECRET'
32 | }) || this;
33 | }
34 | JwtStrategy.prototype.validation = function (payload) {
35 | console.log(payload);
36 | };
37 | JwtStrategy = __decorate([
38 | common_1.Injectable()
39 | ], JwtStrategy);
40 | return JwtStrategy;
41 | }(passport_1.PassportStrategy(passport_jwt_1.Strategy, 'jwt')));
42 | exports.JwtStrategy = JwtStrategy;
43 |
--------------------------------------------------------------------------------
/src/auth/strategy/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./jwt.strategy"
--------------------------------------------------------------------------------
/src/auth/strategy/jwt.strategy.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@nestjs/common";
2 | import { PassportStrategy } from "@nestjs/passport";
3 | import { ExtractJwt, Strategy } from "passport-jwt";
4 | import { PrismaService } from "../../prisma/prisma.service";
5 |
6 | @Injectable()
7 | export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
8 | constructor(private prisma: PrismaService) {
9 | super({
10 | jwtFromRequest:
11 | ExtractJwt.fromAuthHeaderAsBearerToken(),
12 | secretOrKey: 'secret_key'
13 | })
14 | }
15 | async validate(payload: {
16 | sub: number;
17 | email: string;
18 | }) {
19 | const user = await this.prisma.user.findMany(
20 | {
21 | where:
22 | { email: payload.email, id: payload.sub },
23 | select:
24 | { id: true, email: true, first_name: true, last_name: true, Bookmark: true }
25 | })
26 | return user;
27 | }
28 | }
--------------------------------------------------------------------------------
/src/bookmark/bookmark.controller.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sadrax4/nest-restapi/dee9b156453ccb6f949a80bd83b5e38b36f631b8/src/bookmark/bookmark.controller.ts
--------------------------------------------------------------------------------
/src/bookmark/bookmark.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 |
3 | @Module({})
4 | export class BookmarkModule {}
5 |
--------------------------------------------------------------------------------
/src/bookmark/bookmark.service.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sadrax4/nest-restapi/dee9b156453ccb6f949a80bd83b5e38b36f631b8/src/bookmark/bookmark.service.ts
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { NestFactory } from '@nestjs/core';
2 | import { AppModule } from './app.module';
3 | import { ValidationPipe } from '@nestjs/common';
4 | import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
5 |
6 | async function app() {
7 | const app = await NestFactory.create(AppModule);
8 | const config = new DocumentBuilder()
9 | .addBearerAuth()
10 | .setTitle('CRUD Api')
11 | .setDescription('the documentation of crud api')
12 | .setVersion('1.0')
13 | .addTag("auth")
14 | .addTag("user")
15 | .build();
16 | const document = SwaggerModule.createDocument(app, config);
17 | SwaggerModule.setup('api', app, document);
18 | app.useGlobalPipes(new ValidationPipe({
19 | whitelist: true
20 | }))
21 | await app.listen(3000);
22 | }
23 | app();
24 |
--------------------------------------------------------------------------------
/src/prisma/prisma.module.ts:
--------------------------------------------------------------------------------
1 | import { Global, Module } from '@nestjs/common';
2 | import { PrismaService } from './prisma.service';
3 | import { PrismaClient } from '@prisma/client';
4 |
5 | @Global()
6 | @Module({
7 | providers: [PrismaService],
8 | exports: [PrismaService]
9 | })
10 | export class PrismaModule extends PrismaClient {
11 |
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/prisma/prisma.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | import { ConfigService } from '@nestjs/config';
3 | import { PrismaClient } from '@prisma/client';
4 |
5 | @Injectable()
6 | export class PrismaService extends PrismaClient {
7 | constructor(config: ConfigService) {
8 | super({
9 | datasources: {
10 | db: {
11 | url: config.get("DATABASE_URL")
12 | }
13 | }
14 | }
15 | )
16 | }
17 | cleanDb() {
18 | return this.$transaction([
19 | this.user.deleteMany(),
20 | this.bookmark.deleteMany(),
21 | ])
22 | }
23 | }
--------------------------------------------------------------------------------
/src/user/dto/edit.user.ts:
--------------------------------------------------------------------------------
1 | import { IsNotEmpty, IsString, Max, MaxLength, Min, MinLength } from "class-validator";
2 |
3 | export class EditUser {
4 |
5 | @IsString()
6 | @MinLength(2)
7 | @MaxLength(10)
8 | @IsNotEmpty()
9 | first_name: string
10 |
11 |
12 | @IsString()
13 | @MinLength(2)
14 | @MaxLength(10)
15 | @IsNotEmpty()
16 | last_name: string
17 | }
18 |
--------------------------------------------------------------------------------
/src/user/dto/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./edit.user"
--------------------------------------------------------------------------------
/src/user/user.controller.ts:
--------------------------------------------------------------------------------
1 | import { Body, Controller, Get, Post, Res, Response, UseGuards } from "@nestjs/common";
2 | import { JwtGuard } from "../auth/guard/auth.guard";
3 | import { UserService } from './user.service';
4 | import { GetUser } from "src/auth/decorator/request.decorator";
5 | import { User } from "@prisma/client";
6 | import { EditUser } from "./dto";
7 |
8 | @UseGuards(JwtGuard)
9 | @Controller("user")
10 | export class UserController {
11 | constructor(private userService: UserService) { }
12 | @Get("profile")
13 | profile(@GetUser() user: User): User {
14 | return user;
15 | }
16 |
17 | @Post("edit")
18 | editProfile(@Body() dto: EditUser, @GetUser() user: User) {
19 | return this.userService.editUser(dto, user.id);
20 | }
21 |
22 | @Get("list")
23 | getUserList() {
24 | return this.userService.getUserList()
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/src/user/user.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { UserService } from './user.service';
3 | import { UserController } from './user.controller';
4 | import { JwtModule } from '@nestjs/jwt';
5 |
6 | @Module({
7 | imports: [JwtModule.register({ secret: "secret_key" })],
8 | controllers: [UserController],
9 | providers: [UserService]
10 | })
11 | export class UserModule { }
12 |
--------------------------------------------------------------------------------
/src/user/user.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, InternalServerErrorException } from "@nestjs/common";
2 | import { PrismaService } from "src/prisma/prisma.service";
3 | import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
4 | import { User } from "@prisma/client";
5 | import { EditUser } from "./dto";
6 |
7 | @Injectable()
8 | export class UserService {
9 | constructor(private prisma: PrismaService) { }
10 | async editUser(dto: EditUser, userID: number): Promise<{ msg: string }> {
11 | try {
12 | await this.prisma.user.update({
13 | where: {
14 | id: userID
15 | },
16 | data: {
17 | first_name: dto.first_name,
18 | last_name: dto.last_name
19 | }
20 | })
21 | return { msg: "user updated successfully" }
22 | } catch (error) {
23 | if (error instanceof PrismaClientKnownRequestError)
24 | if (error.code === 'P2025')
25 | throw new InternalServerErrorException("Update failed");
26 | }
27 | }
28 | async getUserList(): Promise {
29 | const users = await this.prisma.user.findMany();
30 | users.map(user => {
31 | delete user.password;
32 | })
33 | return users;
34 | }
35 | }
--------------------------------------------------------------------------------
/test/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { Test } from '@nestjs/testing';
2 | import { AppModule } from '../src/app.module';
3 | import { INestApplication, ValidationPipe } from '@nestjs/common';
4 | import { PrismaService } from '../src/prisma/prisma.service';
5 |
6 | describe("app e2e", () => {
7 | let app: INestApplication;
8 | let prisma: PrismaService;
9 | beforeAll(async () => {
10 | const moduleRef = await Test.createTestingModule(
11 | {
12 | imports: [AppModule]
13 | }).compile();
14 | app = moduleRef.createNestApplication();
15 | app.useGlobalPipes(new ValidationPipe({
16 | whitelist: true
17 | }))
18 | await app.init();
19 | prisma = app.get(PrismaService);
20 | await prisma.cleanDb();
21 | })
22 | afterAll(() => {
23 | app.close();
24 | })
25 | it.todo("should be pass")
26 | })
--------------------------------------------------------------------------------
/test/jest-e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "moduleFileExtensions": ["js", "json", "ts"],
3 | "rootDir": ".",
4 | "testEnvironment": "node",
5 | "testRegex": ".e2e-spec.ts$",
6 | "transform": {
7 | "^.+\\.(t|j)s$": "ts-jest"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "removeComments": true,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "allowSyntheticDefaultImports": true,
9 | "target": "ES2021",
10 | "sourceMap": true,
11 | "outDir": "./dist",
12 | "baseUrl": "./",
13 | "incremental": true,
14 | "skipLibCheck": true,
15 | "strictNullChecks": false,
16 | "noImplicitAny": false,
17 | "strictBindCallApply": false,
18 | "forceConsistentCasingInFileNames": false,
19 | "noFallthroughCasesInSwitch": false
20 | }
21 | }
22 |
--------------------------------------------------------------------------------