xiongzhu 2 年 前
コミット
e11cf9799b

+ 2 - 1
.env

@@ -75,4 +75,5 @@ ZKSYNC_EXPLORER=https://goerli.explorer.zksync.io
 LIQUIDITY_MANAGER_ADDRESS=0x25727b360604E1e6B440c3B25aF368F54fc580B6
 TOKEN_ADDRESS=0x0faF6df7054946141266420b43783387A78d82A9
 QUOTER_ADDRESS=0xE93D1d35a63f7C6b51ef46a27434375761a7Db28
-SWAP_ADDRESS=0x3040EE148D09e5B92956a64CDC78b49f48C0cDdc
+SWAP_ADDRESS=0x3040EE148D09e5B92956a64CDC78b49f48C0cDdc
+MINT_ADDRESS=0x74E6d686F70fD5829f00dB0F95EC0f153970baD3

+ 12 - 2
fix.js

@@ -1,6 +1,16 @@
-import  fs  from 'fs'
+const fs = require('fs')
 
 const packageJson = JSON.parse(fs.readFileSync('./node_modules/bignumber.js/package.json', 'utf8'))
 packageJson.exports['./bignumber'] = './bignumber.js'
 fs.writeFileSync('./node_modules/bignumber.js/package.json', JSON.stringify(packageJson, null, 2))
-console.log('Fixed bignumber.js package.json')
+console.log('Fixed bignumber.js package.json')
+
+const file = './node_modules/web3-eth-contract/types/index.d.ts'
+fs.writeFileSync(
+    file,
+    fs
+        .readFileSync(file, 'utf8')
+        .toString()
+        .replace(/Accounts/g, 'Web3Account')
+)
+console.log('Fixed web3-eth-contract')

+ 1 - 1
package.json

@@ -49,7 +49,6 @@
     "bignumber.js": "^9.1.1",
     "class-transformer": "^0.5.1",
     "class-validator": "^0.13.0",
-    "crypto": "^1.0.1",
     "date-fns": "^2.29.3",
     "ethers": "~5.7.0",
     "eventsource-parser": "^1.0.0",
@@ -59,6 +58,7 @@
     "hbs": "^4.2.0",
     "ioredis": "^5.3.2",
     "isomorphic-fetch": "^3.0.0",
+    "iziswap-sdk": "^1.2.2",
     "keyv": "^4.5.2",
     "mongodb": "^5.2.0",
     "mongoose": "^7.0.4",

+ 1 - 1
src/auth/auth.controller.ts

@@ -5,7 +5,7 @@ import { ApiTags } from '@nestjs/swagger'
 import { Public } from './public.decorator'
 import { HasRoles } from './roles.decorator'
 import { Role } from '../model/role.enum'
-import { UserRegisterDto } from 'src/users/dto/user-register.dto'
+import { UserRegisterDto } from '../users/dto/user-register.dto'
 
 @ApiTags('auth')
 @Controller('/auth')

+ 2 - 2
src/auth/auth.service.ts

@@ -2,8 +2,8 @@ import { PhoneLoginDto } from './dto/login.dto'
 import { Injectable, UnauthorizedException } from '@nestjs/common'
 import { JwtService } from '@nestjs/jwt'
 import { UsersService } from '../users/users.service'
-import { Role } from 'src/model/role.enum'
-import { UserRegisterDto } from 'src/users/dto/user-register.dto'
+import { Role } from '../model/role.enum'
+import { UserRegisterDto } from '../users/dto/user-register.dto'
 
 @Injectable()
 export class AuthService {

+ 2 - 2
src/auth/jwt.strategy.ts

@@ -3,8 +3,8 @@ import { PassportStrategy } from '@nestjs/passport'
 import { Inject, Injectable, Logger, UnauthorizedException } from '@nestjs/common'
 import jwtconfig from './jwt.config'
 import { ConfigType } from '@nestjs/config'
-import { UsersService } from 'src/users/users.service'
-import { Role } from 'src/model/role.enum'
+import { UsersService } from '../users/users.service'
+import { Role } from '../model/role.enum'
 
 @Injectable()
 export class JwtStrategy extends PassportStrategy(Strategy) {

+ 1 - 1
src/download/download.controller.ts

@@ -1,5 +1,5 @@
 import { Controller, Get, Query, Render } from '@nestjs/common'
-import { Public } from 'src/auth/public.decorator'
+import { Public } from '../auth/public.decorator'
 
 @Controller('download')
 export class DownloadController {

+ 1 - 1
src/gallery/entities/gallery.entity.ts

@@ -1,4 +1,4 @@
-import { ArrayTransformer } from 'src/transformers/array.transformer'
+import { ArrayTransformer } from '../../transformers/array.transformer'
 import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } from 'typeorm'
 
 @Entity()

+ 5 - 0
src/main.ts

@@ -5,6 +5,7 @@ import { ConfigService } from '@nestjs/config'
 import { configureSwaggerDocs } from './helpers/configure-swagger-docs.helper'
 import { NestExpressApplication } from '@nestjs/platform-express'
 import { join } from 'path'
+declare const module: any
 
 async function bootstrap() {
     const app = await NestFactory.create<NestExpressApplication>(AppModule, {
@@ -39,6 +40,10 @@ async function bootstrap() {
     const port = configService.get<number>('NODE_API_PORT') || 3000
     await app.listen(port)
     Logger.log(`Url for OpenApi: ${await app.getUrl()}/docs`, 'Swagger')
+    if (module.hot) {
+        module.hot.accept()
+        module.hot.dispose(() => app.close())
+    }
 }
 bootstrap().catch((err) => {
     Logger.error(err, 'Bootstrap')

+ 0 - 1
src/sys-config/sys-config.admin.controller.ts

@@ -2,7 +2,6 @@ import { Body, Controller, Get, Param, Post, Put } from '@nestjs/common'
 import { ApiTags } from '@nestjs/swagger'
 import { Public } from '../auth/public.decorator'
 import { SysConfigService } from './sys-config.service'
-import { PageRequest } from 'src/common/dto/page-request'
 import { SysConfig } from './entities/sys-config.entity'
 
 @ApiTags('sys-config.admin')

+ 1 - 1
src/sys-config/sys-config.controller.ts

@@ -3,7 +3,7 @@ import { ApiTags } from '@nestjs/swagger'
 import { Public } from '../auth/public.decorator'
 import { SysConfigService } from './sys-config.service'
 import { SysConfig, SysConfigType } from './entities/sys-config.entity'
-import { PageRequest } from 'src/common/dto/page-request'
+import { PageRequest } from '../common/dto/page-request'
 
 @ApiTags('sys-config')
 @Controller('/sys-config')

+ 1 - 1
src/sys-config/sys-config.service.ts

@@ -2,7 +2,7 @@ import { Injectable, InternalServerErrorException, NotFoundException } from '@ne
 import { InjectRepository } from '@nestjs/typeorm'
 import { Repository } from 'typeorm'
 import { SysConfig } from './entities/sys-config.entity'
-import { PageRequest } from 'src/common/dto/page-request'
+import { PageRequest } from '../common/dto/page-request'
 import { Pagination, paginate } from 'nestjs-typeorm-paginate'
 
 @Injectable()

+ 2 - 2
src/user-balance/user-balance.admin.controller.ts

@@ -1,8 +1,8 @@
 import { Controller } from '@nestjs/common'
 import { UserBalanceService } from './user-balance.service'
 import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
-import { HasRoles } from 'src/auth/roles.decorator'
-import { Role } from 'src/model/role.enum'
+import { HasRoles } from '../auth/roles.decorator'
+import { Role } from '../model/role.enum'
 
 @ApiTags('userBalance.admin')
 @ApiBearerAuth()

+ 1 - 1
src/users/users.admin.controller.ts

@@ -19,7 +19,7 @@ import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
 import { HasRoles } from '../auth/roles.decorator'
 import { Role } from '../model/role.enum'
 import { IPaginationOptions } from 'nestjs-typeorm-paginate'
-import { PageRequest } from 'src/common/dto/page-request'
+import { PageRequest } from '../common/dto/page-request'
 import { Users } from './entities/users.entity'
 import { UserCreateDto } from './dto/user-create.dto'
 

+ 1 - 1
src/users/users.controller.ts

@@ -14,7 +14,7 @@ import { UserProfileDto } from './dto/user-profile.dto'
 import { IUsers } from './interfaces/users.interface'
 import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
 import { Users } from './entities/users.entity'
-import { Public } from 'src/auth/public.decorator'
+import { Public } from '../auth/public.decorator'
 
 @ApiTags('users')
 @Controller('users')

+ 1 - 1
src/users/users.service.ts

@@ -19,7 +19,7 @@ import { HashingService } from '../shared/hashing/hashing.service'
 import { SmsService } from '../sms/sms.service'
 import * as randomstring from 'randomstring'
 import { paginate, Pagination } from 'nestjs-typeorm-paginate'
-import { Role } from 'src/model/role.enum'
+import { Role } from '../model/role.enum'
 import { PageRequest } from '../common/dto/page-request'
 import { endOfDay, startOfDay } from 'date-fns'
 

+ 458 - 0
src/web3/mintSquareAbi.json

@@ -0,0 +1,458 @@
+[
+    {
+        "inputs": [],
+        "stateMutability": "nonpayable",
+        "type": "constructor"
+    },
+    {
+        "anonymous": false,
+        "inputs": [
+            {
+                "indexed": true,
+                "internalType": "address",
+                "name": "owner",
+                "type": "address"
+            },
+            {
+                "indexed": true,
+                "internalType": "address",
+                "name": "approved",
+                "type": "address"
+            },
+            {
+                "indexed": true,
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
+        "name": "Approval",
+        "type": "event"
+    },
+    {
+        "anonymous": false,
+        "inputs": [
+            {
+                "indexed": true,
+                "internalType": "address",
+                "name": "owner",
+                "type": "address"
+            },
+            {
+                "indexed": true,
+                "internalType": "address",
+                "name": "operator",
+                "type": "address"
+            },
+            {
+                "indexed": false,
+                "internalType": "bool",
+                "name": "approved",
+                "type": "bool"
+            }
+        ],
+        "name": "ApprovalForAll",
+        "type": "event"
+    },
+    {
+        "anonymous": false,
+        "inputs": [
+            {
+                "indexed": true,
+                "internalType": "address",
+                "name": "previousOwner",
+                "type": "address"
+            },
+            {
+                "indexed": true,
+                "internalType": "address",
+                "name": "newOwner",
+                "type": "address"
+            }
+        ],
+        "name": "OwnershipTransferred",
+        "type": "event"
+    },
+    {
+        "anonymous": false,
+        "inputs": [
+            {
+                "indexed": true,
+                "internalType": "address",
+                "name": "from",
+                "type": "address"
+            },
+            {
+                "indexed": true,
+                "internalType": "address",
+                "name": "to",
+                "type": "address"
+            },
+            {
+                "indexed": true,
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
+        "name": "Transfer",
+        "type": "event"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "to",
+                "type": "address"
+            },
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
+        "name": "approve",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "owner",
+                "type": "address"
+            }
+        ],
+        "name": "balanceOf",
+        "outputs": [
+            {
+                "internalType": "uint256",
+                "name": "",
+                "type": "uint256"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
+        "name": "getApproved",
+        "outputs": [
+            {
+                "internalType": "address",
+                "name": "",
+                "type": "address"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "owner",
+                "type": "address"
+            },
+            {
+                "internalType": "address",
+                "name": "operator",
+                "type": "address"
+            }
+        ],
+        "name": "isApprovedForAll",
+        "outputs": [
+            {
+                "internalType": "bool",
+                "name": "",
+                "type": "bool"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "string",
+                "name": "uri",
+                "type": "string"
+            }
+        ],
+        "name": "mint",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [],
+        "name": "name",
+        "outputs": [
+            {
+                "internalType": "string",
+                "name": "",
+                "type": "string"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [],
+        "name": "owner",
+        "outputs": [
+            {
+                "internalType": "address",
+                "name": "",
+                "type": "address"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
+        "name": "ownerOf",
+        "outputs": [
+            {
+                "internalType": "address",
+                "name": "",
+                "type": "address"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [],
+        "name": "renounceOwnership",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "from",
+                "type": "address"
+            },
+            {
+                "internalType": "address",
+                "name": "to",
+                "type": "address"
+            },
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
+        "name": "safeTransferFrom",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "from",
+                "type": "address"
+            },
+            {
+                "internalType": "address",
+                "name": "to",
+                "type": "address"
+            },
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            },
+            {
+                "internalType": "bytes",
+                "name": "data",
+                "type": "bytes"
+            }
+        ],
+        "name": "safeTransferFrom",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "operator",
+                "type": "address"
+            },
+            {
+                "internalType": "bool",
+                "name": "approved",
+                "type": "bool"
+            }
+        ],
+        "name": "setApprovalForAll",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "bytes4",
+                "name": "interfaceId",
+                "type": "bytes4"
+            }
+        ],
+        "name": "supportsInterface",
+        "outputs": [
+            {
+                "internalType": "bool",
+                "name": "",
+                "type": "bool"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [],
+        "name": "symbol",
+        "outputs": [
+            {
+                "internalType": "string",
+                "name": "",
+                "type": "string"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "uint256",
+                "name": "index",
+                "type": "uint256"
+            }
+        ],
+        "name": "tokenByIndex",
+        "outputs": [
+            {
+                "internalType": "uint256",
+                "name": "",
+                "type": "uint256"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "owner",
+                "type": "address"
+            },
+            {
+                "internalType": "uint256",
+                "name": "index",
+                "type": "uint256"
+            }
+        ],
+        "name": "tokenOfOwnerByIndex",
+        "outputs": [
+            {
+                "internalType": "uint256",
+                "name": "",
+                "type": "uint256"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
+        "name": "tokenURI",
+        "outputs": [
+            {
+                "internalType": "string",
+                "name": "",
+                "type": "string"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [],
+        "name": "totalSupply",
+        "outputs": [
+            {
+                "internalType": "uint256",
+                "name": "",
+                "type": "uint256"
+            }
+        ],
+        "stateMutability": "view",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "from",
+                "type": "address"
+            },
+            {
+                "internalType": "address",
+                "name": "to",
+                "type": "address"
+            },
+            {
+                "internalType": "uint256",
+                "name": "tokenId",
+                "type": "uint256"
+            }
+        ],
+        "name": "transferFrom",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    },
+    {
+        "inputs": [
+            {
+                "internalType": "address",
+                "name": "newOwner",
+                "type": "address"
+            }
+        ],
+        "name": "transferOwnership",
+        "outputs": [],
+        "stateMutability": "nonpayable",
+        "type": "function"
+    }
+]

+ 1 - 0
src/web3/web3.config.ts

@@ -16,5 +16,6 @@ export default registerAs('web3', () => {
         tokenAddress: configService.get<string>('TOKEN_ADDRESS'),
         quoterAddress: configService.get<string>('QUOTER_ADDRESS'),
         swapAddress: configService.get<string>('SWAP_ADDRESS'),
+        mintAddress: configService.get<string>('MINT_ADDRESS'),
     }
 })

+ 5 - 0
src/web3/web3.controller.ts

@@ -29,4 +29,9 @@ export class Web3Controller {
     public async swap(@Body() { accountId, amount }) {
         return await this.web3Service.swapWithExactOutput(accountId, amount)
     }
+
+    @Post('/mint')
+    public async mint(@Body() { accountId }) {
+        return await this.web3Service.mint(accountId)
+    }
 }

+ 1 - 1
src/web3/web3.module.ts

@@ -3,7 +3,7 @@ import { Web3Service } from './web3.service'
 import { Web3Controller } from './web3.controller'
 import { ConfigModule } from '@nestjs/config'
 import web3Config from './web3.config'
-import { AccountsModule } from 'src/accounts/accounts.module'
+import { AccountsModule } from '../accounts/accounts.module'
 
 @Module({
     imports: [ConfigModule.forFeature(web3Config), AccountsModule],

+ 25 - 1
src/web3/web3.service.ts

@@ -3,7 +3,7 @@ import { ethers } from 'ethers'
 import { Wallet, Provider, utils } from 'zksync-web3'
 import web3Config from './web3.config'
 import { ConfigType } from '@nestjs/config'
-import { AccountsService } from 'src/accounts/accounts.service'
+import { AccountsService } from '../accounts/accounts.service'
 import erc20 from './erc20.json'
 import {
     ChainId,
@@ -35,6 +35,7 @@ import {
 import { getPoolContract, getPoolState, getPointDelta } from 'iziswap-sdk/lib/pool'
 import { getQuoterContract, quoterSwapChainWithExactOutput } from 'iziswap-sdk/lib/quoter'
 import { getSwapContract, getSwapChainWithExactOutputCall } from 'iziswap-sdk/lib/swap'
+import mintSquareAbi from './mintSquareAbi.json'
 
 @Injectable()
 export class Web3Service {
@@ -367,4 +368,27 @@ export class Web3Service {
         })
         console.log(tx)
     }
+
+    async mint(accountId) {
+        const account = await this.accountService.findById(accountId)
+        const chainId = this.web3Configuration.ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
+        const chain = initialChainTable[chainId]
+        const provider = new Provider(this.web3Configuration.zksyncRpcUrl)
+        const wallet = new Wallet(account.privateKey).connect(provider)
+        const web3 = new Web3(new Web3.providers.HttpProvider(this.web3Configuration.zksyncRpcUrl))
+        console.log('address: ', wallet.address)
+
+        const contract = new web3.eth.Contract(mintSquareAbi, this.web3Configuration.mintAddress, web3 as any)
+        // @ts-ignore
+        const mintCall = await contract.methods.mint('ipfs://QmPxcRPvjMDrv7d4WjQK5KNXkuXudGhKjPTDnzuFkRQ6Fs')
+        const gasLimit = await mintCall.estimateGas({ from: wallet.address })
+        console.log('gas limit: ', gasLimit)
+        const tx = await wallet.sendTransaction({
+            from: wallet.address,
+            to: this.web3Configuration.mintAddress,
+            data: mintCall.encodeABI(),
+            gasLimit
+        })
+        console.log(tx)
+    }
 }

+ 0 - 82
test/app.e2e-spec.ts

@@ -1,82 +0,0 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import * as request from 'supertest';
-import { AppModule } from '../src/app.module';
-import { HttpStatus, ValidationPipe } from '@nestjs/common';
-
-describe('App (e2e)', () => {
-  let app;
-  let accessTokenJwt: string;
-
-  beforeAll(async () => {
-    const moduleFixture: TestingModule = await Test.createTestingModule({
-      imports: [AppModule],
-    })
-      .compile();
-
-    app = moduleFixture.createNestApplication();
-    app.setGlobalPrefix('api');
-    app.useGlobalPipes(
-      new ValidationPipe({
-        whitelist: true,
-        transform: true,
-        forbidNonWhitelisted: true,
-        transformOptions: {
-          enableImplicitConversion: true,
-        },
-      }),
-    );
-    await app.init();
-  });
-
-  describe('AppController (e2e)', () => {
-    it('should return the follwing message: "This is a simple example of item returned by your APIs." [GET /api]', () => {
-      return request(app.getHttpServer())
-        .get('/api')
-        .expect({
-          message: 'This is a simple example of item returned by your APIs.',
-        })
-        .expect(HttpStatus.OK);
-    });
-
-    describe('should sign in and get a "live" JWT', () => {
-      it('should authenticates user with valid credentials and provides a jwt token', () => {
-        return request(app.getHttpServer())
-          .post('/api/auth/login')
-          .send({
-            email: 'test@example.com',
-            password: 'pass123',
-          })
-          .then(({ body }) => {
-            accessTokenJwt = body.accessToken;
-            expect(accessTokenJwt).toMatch(
-              /^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/,
-            );
-            expect(body).toEqual({
-              sub: 1,
-              expiresIn: '3600',
-              audience: '127.0.0.1:3001',
-              issuer: '127.0.0.1:3001',
-              accessToken: accessTokenJwt,
-              user: { name: 'name #1', email: 'test@example.com', id: 1 },
-            });
-
-            expect(HttpStatus.OK);
-          });
-      });
-
-      it('should return the follwing message: "Access to protected resources granted! This protected resource is displayed when the token is successfully provided". - ( endpoint protected ) [GET /api/secure]', () => {
-        return request(app.getHttpServer())
-          .get('/api/secure')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .expect({
-            message:
-              'Access to protected resources granted! This protected resource is displayed when the token is successfully provided.',
-          });
-      });
-    });
-  });
-
-  afterAll(async () => {
-    await app.close();
-  });
-});

+ 0 - 118
test/login/login.e2e-spec.ts

@@ -1,118 +0,0 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import * as request from 'supertest';
-import { AppModule } from './../../src/app.module';
-import {
-  BadRequestException,
-  HttpStatus,
-  ValidationPipe,
-} from '@nestjs/common';
-
-describe('App (e2e)', () => {
-  let app;
-
-  beforeAll(async () => {
-    const moduleFixture: TestingModule = await Test.createTestingModule({
-      imports: [AppModule],
-    }).compile();
-
-    app = moduleFixture.createNestApplication();
-    app.setGlobalPrefix('api');
-    app.useGlobalPipes(
-      new ValidationPipe({
-        whitelist: true,
-        transform: true,
-        forbidNonWhitelisted: true,
-        transformOptions: {
-          enableImplicitConversion: true,
-        },
-      }),
-    );
-
-    await app.init();
-  });
-
-  describe('LoginController (e2e) -  [POST /api/auth/login]', () => {
-    let accessTokenJwt: string;
-
-    it('should authenticates user with valid credentials and provides a jwt token', () => {
-      return request(app.getHttpServer())
-        .post('/api/auth/login')
-        .send({
-          email: 'test@example.com',
-          password: 'pass123',
-        })
-        .then(({ body }) => {
-          accessTokenJwt = body.accessToken;
-          expect(accessTokenJwt).toMatch(
-            /^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/,
-          );
-
-          expect(body).toEqual({
-            sub: 1,
-            expiresIn: '3600',
-            audience: '127.0.0.1:3001',
-            issuer: '127.0.0.1:3001',
-            accessToken: accessTokenJwt,
-            user: { name: 'name #1', email: 'test@example.com', id: 1 },
-          });
-
-          expect(HttpStatus.OK);
-        });
-    });
-
-    it('should fails to authenticate user with an incorrect password', async () => {
-      const response = await request(app.getHttpServer())
-        .post('/api/auth/login')
-        .send({ email: 'test@example.com', password: 'wrong' })
-        .expect(HttpStatus.BAD_REQUEST);
-
-      expect(response.body.accessToken).not.toBeDefined();
-    });
-
-    it('should throw an error for a bad email', () => {
-      return request(app.getHttpServer())
-        .post('/api/auth/login')
-        .send({
-          password: 'pass123',
-        })
-        .then(({ body }) => {
-          expect(body).toEqual({
-            error: 'Bad Request',
-            message: [
-              'email should not be empty',
-              'email must be a string',
-              'email must be an email',
-            ],
-            statusCode: 400,
-          });
-          expect(HttpStatus.BAD_REQUEST);
-          expect(new BadRequestException());
-        });
-    });
-
-    it('should throw an error for a bad password', () => {
-      return request(app.getHttpServer())
-        .post('/api/auth/login')
-        .send({
-          email: 'test@example.it',
-        })
-        .then(({ body }) => {
-          expect(body).toEqual({
-            error: 'Bad Request',
-            message: [
-              'password must be shorter than or equal to 60 characters',
-              'password must be a string',
-              'password should not be empty',
-            ],
-            statusCode: 400,
-          });
-          expect(HttpStatus.BAD_REQUEST);
-          expect(new BadRequestException());
-        });
-    });
-  });
-
-  afterAll(async () => {
-    await app.close();
-  });
-});

+ 0 - 165
test/register/register.e2e-spec.ts

@@ -1,165 +0,0 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import * as request from 'supertest';
-import { AppModule } from './../../src/app.module';
-import { MailerService } from '../../src/shared/mailer/mailer.service';
-import {
-  BadRequestException,
-  HttpStatus,
-  ValidationPipe,
-} from '@nestjs/common';
-import { UserCreateDto } from 'src/users/dto/user-create.dto';
-import { HashingService } from '../../src/shared/hashing/hashing.service';
-
-const user = {
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'pass123',
-};
-
-describe('App (e2e)', () => {
-  let app;
-
-  beforeAll(async () => {
-    const moduleFixture: TestingModule = await Test.createTestingModule({
-      imports: [AppModule],
-      providers: [
-        {
-          provide: HashingService,
-          useValue: {
-            hash: jest.fn(() => 'pass123'),
-          },
-        },
-      ],
-    })
-      .overrideProvider(MailerService)
-      .useValue({
-        sendMail: jest.fn(() => true),
-      })
-      .compile();
-
-    app = moduleFixture.createNestApplication();
-    app.setGlobalPrefix('api');
-    app.useGlobalPipes(
-      new ValidationPipe({
-        whitelist: true,
-        transform: true,
-        forbidNonWhitelisted: true,
-        transformOptions: {
-          enableImplicitConversion: true,
-        },
-      }),
-    );
-
-    await app.init();
-  });
-
-  describe('RegisterController (e2e) - [POST /api/auth/register]', () => {
-    it('should register user', async () => {
-      return await request(app.getHttpServer())
-        .post('/api/auth/register')
-        .send(user as UserCreateDto)
-        .then(({ body }) => {
-          expect(body).toEqual({
-            message: 'User registration successfully!',
-            status: 201,
-          });
-          expect(HttpStatus.CREATED);
-        });
-    });
-
-    it('should throw an error for a bad email', async () => {
-      return await request(app.getHttpServer())
-        .post('/api/auth/register')
-        .send({
-          name: 'name#1 register',
-          username: 'username#1 register',
-          password: '123456789',
-        })
-        .then(({ body }) => {
-          expect(body).toEqual({
-            error: 'Bad Request',
-            message: [
-              'email should not be empty',
-              'email must be a string',
-              'email must be an email',
-            ],
-            statusCode: 400,
-          });
-          expect(HttpStatus.BAD_REQUEST);
-          expect(new BadRequestException());
-        });
-    });
-
-    it('should throw an error for a bad name', async () => {
-      return await request(app.getHttpServer())
-        .post('/api/auth/register')
-        .send({
-          username: 'username#1 register',
-          email: 'test@example.it',
-          password: '123456789',
-        })
-        .expect(HttpStatus.BAD_REQUEST)
-        .then(({ body }) => {
-          expect(body).toEqual({
-            error: 'Bad Request',
-            message: [
-              'name must be shorter than or equal to 30 characters',
-              'name must be a string',
-            ],
-            statusCode: 400,
-          });
-          expect(new BadRequestException());
-        });
-    });
-
-    it('should throw an error for a bad username', async () => {
-      return await request(app.getHttpServer())
-        .post('/api/auth/register')
-        .send({
-          name: 'name#1 register',
-          email: 'test@example.it',
-          password: '123456789',
-        })
-        .then(({ body }) => {
-          expect(body).toEqual({
-            error: 'Bad Request',
-            message: [
-              'username must be shorter than or equal to 40 characters',
-              'username must be a string',
-            ],
-            statusCode: 400,
-          });
-          expect(HttpStatus.BAD_REQUEST);
-          expect(new BadRequestException());
-        });
-    });
-
-    it('should throw an error for a bad password', async () => {
-      return await request(app.getHttpServer())
-        .post('/api/auth/register')
-        .send({
-          name: 'name#1 register',
-          username: 'username#1 register',
-          email: 'test@example.it',
-        })
-        .then(({ body }) => {
-          expect(body).toEqual({
-            error: 'Bad Request',
-            message: [
-              'password must be shorter than or equal to 60 characters',
-              'password must be a string',
-              'password should not be empty',
-            ],
-            statusCode: 400,
-          });
-          expect(HttpStatus.BAD_REQUEST);
-          expect(new BadRequestException());
-        });
-    });
-  });
-
-  afterAll(async () => {
-    await app.close();
-  });
-});

+ 0 - 246
test/users/users.e2e-spec.ts

@@ -1,246 +0,0 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import * as request from 'supertest';
-import { AppModule } from './../../src/app.module';
-import { MailerService } from '../../src/shared/mailer/mailer.service';
-import { HttpStatus, ValidationPipe } from '@nestjs/common';
-import { AccessTokenGuard } from '../../src/iam/login/guards/access-token/access-token.guard';
-
-const users = [
-  {
-    id: 1,
-    name: 'name #1',
-    username: 'username #1',
-    email: 'test1@example.com',
-    password: 'pass123',
-  },
-];
-
-const updateProfileUserDto = {
-  name: 'name#1 update',
-  username: 'username#1 update',
-  email: 'test@example.it',
-};
-
-describe('App (e2e)', () => {
-  let app;
-  let accessTokenJwt: string;
-
-  beforeAll(async () => {
-    const moduleFixture: TestingModule = await Test.createTestingModule({
-      imports: [AppModule],
-    })
-      .overrideProvider(MailerService)
-      .useValue({
-        sendMail: jest.fn(() => true),
-      })
-      .overrideGuard(AccessTokenGuard)
-      .useValue({ canActivate: () => true })
-      .compile();
-
-    app = moduleFixture.createNestApplication();
-    app.setGlobalPrefix('api');
-    app.useGlobalPipes(
-      new ValidationPipe({
-        whitelist: true,
-        transform: true,
-        forbidNonWhitelisted: true,
-        transformOptions: {
-          enableImplicitConversion: true,
-        },
-      }),
-    );
-
-    await app.init();
-  });
-
-  describe('UserController (e2e)', () => {
-    describe('should sign in and get a "live" JWT', () => {
-      it('should authenticates user with valid credentials and provides a jwt token', () => {
-        return request(app.getHttpServer())
-          .post('/api/auth/login')
-          .send({
-            email: 'test@example.com',
-            password: 'pass123',
-          })
-          .then(({ body }) => {
-            accessTokenJwt = body.accessToken;
-            expect(accessTokenJwt).toMatch(
-              /^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/,
-            );
-
-            expect(body).toEqual({
-              sub: 1,
-              expiresIn: '3600',
-              audience: '127.0.0.1:3001',
-              issuer: '127.0.0.1:3001',
-              accessToken: accessTokenJwt,
-              user: { name: 'name #1', email: 'test@example.com', id: 1 },
-            });
-
-            expect(HttpStatus.OK);
-          });
-      });
-    });
-    describe('Get all users [GET /api/users]', () => {
-      it('should get all users', async () => {
-        return await request(app.getHttpServer())
-          .get('/api/users')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .expect(HttpStatus.OK)
-          .then(({ body }) => {
-            expect(body).toEqual([
-              {
-                id: 1,
-                name: 'name #1',
-                username: 'username #1',
-                email: 'test@example.com',
-                password: body[0].password,
-              },
-            ]);
-          });
-      });
-    });
-
-    describe('Get one user [GET /api/users/:id]', () => {
-      it('should get one user', async () => {
-        return await request(app.getHttpServer())
-          .get('/api/users/1')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .expect(HttpStatus.OK)
-          .then(({ body }) => {
-            expect(body).toEqual({
-              id: 1,
-              name: 'name #1',
-              username: 'username #1',
-              email: 'test@example.com',
-              password: body.password,
-            });
-          });
-      });
-
-      it('should return an incorrect request if it does not find the id', async () => {
-        return await request(app.getHttpServer())
-          .get('/api/users/30')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .then(({ body }) => {
-            expect(body).toEqual({
-              error: 'Not Found',
-              message: 'User #30 not found',
-              statusCode: HttpStatus.NOT_FOUND,
-            });
-          });
-      });
-    });
-
-    describe('Get one user profile [GET /api/users/:id/profile]', () => {
-      it('should get one user profile', async () => {
-        return await request(app.getHttpServer())
-          .get('/api/users/1/profile')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .expect(HttpStatus.OK)
-          .then(({ body }) => {
-            expect(body).toEqual({
-              user: {
-                id: 1,
-                name: 'name #1',
-                username: 'username #1',
-                email: 'test@example.com',
-                password: body.user.password,
-              },
-              status: HttpStatus.OK,
-            });
-          });
-      });
-
-      it('should return an incorrect request if it does not find the user profile id', async () => {
-        return await request(app.getHttpServer())
-          .get('/api/users/20/profile')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .expect(HttpStatus.NOT_FOUND);
-      });
-    });
-
-    describe('Update one user profile [PUT /api/users/:id/profile]', () => {
-      it('should update one user profile by id', async () => {
-        return await request(app.getHttpServer())
-          .put('/api/users/1/profile')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .send({
-            name: 'name #1',
-            username: 'username #1',
-            email: 'test@example.com',
-          })
-          .expect(HttpStatus.OK)
-          .then(({ body }) => {
-            expect(body).toEqual({
-              message: 'User Updated successfully!',
-              status: HttpStatus.OK,
-            });
-          });
-      });
-
-      it('should return an incorrect request if it does not find the id', async () => {
-        return await request(app.getHttpServer())
-          .put('/api/users/10/profile')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .send(updateProfileUserDto)
-          .expect(HttpStatus.BAD_REQUEST);
-      });
-    });
-    //
-    describe('Update one user [PUT /api/users/:id]', () => {
-      it('should update one user', async () => {
-        return await request(app.getHttpServer())
-          .put('/api/users/1')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .send({
-            name: 'name #1',
-            username: 'username #1',
-            email: 'test@example.com',
-            password:
-              '$2b$10$hgJzgGh2tkqqIYpIYQI9pO0Q1S9Vd.OXnJcsm1oA1nYvd9yet8sxi',
-          })
-          .expect(HttpStatus.OK)
-          .then(({ body }) => {
-            expect(body).toEqual({
-              message: 'User Updated successfully!',
-              status: HttpStatus.OK,
-            });
-          });
-      });
-
-      it('should return an incorrect request if it does not find the id', async () => {
-        return await request(app.getHttpServer())
-          .put('/api/users/10')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .send(null)
-          .expect(HttpStatus.BAD_REQUEST);
-      });
-    });
-
-    describe('Delete on user [DELETE /api/users/:id]', () => {
-      it('should delete one user by id', async () => {
-        return await request(app.getHttpServer())
-          .delete('/api/users/1')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .expect(HttpStatus.OK)
-          .then(() => {
-            return request(app.getHttpServer())
-              .get('/users/1')
-              .expect(HttpStatus.NOT_FOUND);
-          });
-      });
-
-      it('should return an incorrect request if it does not find the id', () => {
-        return request(app.getHttpServer())
-          .delete('/api/users/10')
-          .set('Authorization', `Bearer ${accessTokenJwt}`)
-          .expect(HttpStatus.NOT_FOUND);
-      });
-    });
-  });
-
-  afterAll(async () => {
-    await app.close();
-  });
-});

+ 0 - 5
yarn.lock

@@ -3382,11 +3382,6 @@ crypt@0.0.2:
   resolved "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz"
   integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==
 
-crypto@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.npmmirror.com/crypto/-/crypto-1.0.1.tgz#2af1b7cad8175d24c8a1b0778255794a21803037"
-  integrity sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==
-
 d@1, d@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmmirror.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"