diff --git a/package.json b/package.json index 9671466..62e310c 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "prebuild": "rimraf dist", "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", - "dev":"nest start --watch", + "dev": "nest start --watch", "start": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", @@ -24,10 +24,18 @@ "@hapi/joi": "^16.1.8", "@nestjs/common": "^6.7.2", "@nestjs/core": "^6.7.2", + "@nestjs/jwt": "^6.1.1", "@nestjs/mongoose": "^6.1.2", + "@nestjs/passport": "^6.1.0", "@nestjs/platform-express": "^6.7.2", + "@types/moment": "^2.13.0", + "axios": "^0.19.0", "dotenv": "^8.2.0", + "fast-xml-parser": "^3.15.0", + "moment": "^2.24.0", "mongoose": "^5.7.12", + "passport": "^0.4.0", + "passport-jwt": "^4.0.0", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.0", "rxjs": "^6.5.3" @@ -36,11 +44,13 @@ "@nestjs/cli": "^6.9.0", "@nestjs/schematics": "^6.7.0", "@nestjs/testing": "^6.7.1", + "@types/axios": "^0.14.0", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.1", "@types/hapi__joi": "^16.0.3", "@types/jest": "^24.0.18", "@types/node": "^12.7.5", + "@types/passport-jwt": "^3.0.3", "@types/supertest": "^2.0.8", "jest": "^24.9.0", "prettier": "^1.18.2", diff --git a/src/app.controller.spec.ts b/src/app.controller.spec.ts deleted file mode 100644 index d22f389..0000000 --- a/src/app.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; - -describe('AppController', () => { - let appController: AppController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [AppController], - providers: [AppService], - }).compile(); - - appController = app.get(AppController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(appController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/src/app.module.ts b/src/app.module.ts index 1d88eed..482185e 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,6 +4,7 @@ import { AppService } from './app.service'; import { ConfigModule } from './config/config.module'; import { ConfigService } from './config/config.service'; import { MongooseModule } from '@nestjs/mongoose'; +import { AuthModule } from './auth/auth.module'; const mongooseModule = MongooseModule.forRootAsync({ imports: [ConfigModule], @@ -16,7 +17,7 @@ const mongooseModule = MongooseModule.forRootAsync({ }); @Module({ - imports: [ConfigModule, mongooseModule], + imports: [ConfigModule, mongooseModule, AuthModule], controllers: [AppController], providers: [AppService], }) diff --git a/src/auth/auth.controller.spec.ts b/src/auth/auth.controller.spec.ts new file mode 100644 index 0000000..5695209 --- /dev/null +++ b/src/auth/auth.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AuthController } from './auth.controller'; + +describe('Auth Controller', () => { + let controller: AuthController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [AuthController], + }).compile(); + + controller = module.get(AuthController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts new file mode 100644 index 0000000..4fa20e2 --- /dev/null +++ b/src/auth/auth.controller.ts @@ -0,0 +1,21 @@ +import { Controller, Query, Get, Param } from '@nestjs/common'; +import { AuthService } from './auth.service'; + +@Controller('auth') +export class AuthController { + constructor(private readonly authService: AuthService){} + @Get('/ids-auth') + async idsAuth(@Query('ticket') ticket: string){ + return { access_token:(await this.authService.authWithIdsTicket(ticket)) }; + } + + @Get('/ids-auth/:wechatSession') + async idsAuthWithWechatSession(@Query('ticket') ticket: string, @Param('wechatSession') wechatSession: string){ + + } + + @Get('/wechat-auth') + async wechatAuth(@Query('code') code: string){ + + } +} diff --git a/src/auth/auth.interface.ts b/src/auth/auth.interface.ts new file mode 100644 index 0000000..8c84e51 --- /dev/null +++ b/src/auth/auth.interface.ts @@ -0,0 +1,8 @@ +import { Document } from 'mongoose'; + +export interface Auth extends Document { + readonly cardnum: string; + readonly name: string; + readonly openId: string; + readonly wechatSession: string, +} \ No newline at end of file diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts new file mode 100644 index 0000000..b27f559 --- /dev/null +++ b/src/auth/auth.module.ts @@ -0,0 +1,26 @@ +import { Module, Injectable } from '@nestjs/common'; +import { AuthService } from './auth.service'; +import { ConfigService } from '../config/config.service'; +import { JwtModule } from '@nestjs/jwt'; +import { PassportModule } from '@nestjs/passport'; +import { JwtStrategy } from './jwt.strategy'; +import { AuthController } from './auth.controller'; +import { MongooseModule } from '@nestjs/mongoose'; +import { AuthSchema } from './auth.scheme'; + +const config = new ConfigService() + +@Module({ + imports: [ + PassportModule, + JwtModule.register({ + secret: config.jwtSecret, + signOptions: { expiresIn: '3h' }, + }), + MongooseModule.forFeature([{ name: 'Auth', schema: AuthSchema }]) + ], + providers: [AuthService, JwtStrategy], + exports: [ AuthService ], + controllers: [AuthController] +}) +export class AuthModule {} diff --git a/src/auth/auth.scheme.ts b/src/auth/auth.scheme.ts new file mode 100644 index 0000000..612ab9a --- /dev/null +++ b/src/auth/auth.scheme.ts @@ -0,0 +1,9 @@ +import * as mongoose from 'mongoose'; + +export const AuthSchema = new mongoose.Schema({ + name: String, // 姓名 + cardnum: String, // 一卡通号 + openId: String, // 微信公众号 OpenId + wechatSession: String, // 微信绑定过程中会话标识符 + lastAuthTime: Number, // 最近认证时间 +}); \ No newline at end of file diff --git a/src/auth/auth.service.spec.ts b/src/auth/auth.service.spec.ts new file mode 100644 index 0000000..800ab66 --- /dev/null +++ b/src/auth/auth.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AuthService } from './auth.service'; + +describe('AuthService', () => { + let service: AuthService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AuthService], + }).compile(); + + service = module.get(AuthService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts new file mode 100644 index 0000000..81ffe28 --- /dev/null +++ b/src/auth/auth.service.ts @@ -0,0 +1,44 @@ +import { Injectable } from '@nestjs/common'; +import { ConfigService } from '../config/config.service'; +import axios from 'axios'; +import { parse as xmlParser } from 'fast-xml-parser'; +import { InjectModel } from '@nestjs/mongoose'; +import { Auth } from './auth.interface'; +import { Model } from 'mongoose'; +import * as moment from 'moment'; +import { JwtService } from '@nestjs/jwt'; + +@Injectable() +export class AuthService { + constructor(private readonly config: ConfigService, + @InjectModel('Auth') private readonly authModel:Model, + private readonly jwtService:JwtService + ) {} + + async authWithIdsTicket(ticket: string): Promise{ + const validateUrl = `${this.config.idsValidatedUrl}?service=${this.config.idsAuthUrl}&ticket=${ticket}`; + const res = await axios.get(validateUrl); + const rawIdsData = xmlParser(res.data); + try { + let { "cas:uid":cardnum, "cas:cn":name } = rawIdsData["cas:serviceResponse"]["cas:authenticationSuccess"]["cas:attributes"]; + let record = await this.authModel.findOne({ cardnum }); + if(!record){ + record = new this.authModel({ cardnum, name }) + } + record.lastAuthTime = moment().unix(); + await record.save(); + return this.jwtService.sign({ cardnum, name }); + } catch (e) { + console.log(e) + return null + } + } + + async authWithWechatCode(code: string): Promise{ + return 'wechatSession' + } + + async authWithIdsTicketAndWechatSession(ticket: string, wechatSession: string){ + + } +} diff --git a/src/auth/jwt.strategy.ts b/src/auth/jwt.strategy.ts new file mode 100644 index 0000000..75cc50f --- /dev/null +++ b/src/auth/jwt.strategy.ts @@ -0,0 +1,19 @@ +import { ExtractJwt, Strategy } from 'passport-jwt'; +import { PassportStrategy } from '@nestjs/passport'; +import { Injectable } from '@nestjs/common'; +import { ConfigService } from '../config/config.service'; + +@Injectable() +export class JwtStrategy extends PassportStrategy(Strategy) { + constructor(private readonly configService: ConfigService) { + super({ + jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), + ignoreExpiration: false, + secretOrKey: configService.jwtSecret, + }); + } + + async validate(payload: any) { + return { cardnum: payload.cardnum }; + } +} \ No newline at end of file diff --git a/src/config/config.module.ts b/src/config/config.module.ts index 3ebe412..000bc68 100644 --- a/src/config/config.module.ts +++ b/src/config/config.module.ts @@ -6,7 +6,7 @@ import { ConfigService } from './config.service'; providers: [ { provide: ConfigService, - useValue: new ConfigService(`${process.env.NODE_ENV || 'development'}.env`), + useValue: new ConfigService(), }, ], exports: [ConfigService], diff --git a/src/config/config.service.ts b/src/config/config.service.ts index 60a6d6b..2a865f5 100644 --- a/src/config/config.service.ts +++ b/src/config/config.service.ts @@ -7,7 +7,7 @@ export type EnvConfig = Record; export class ConfigService { private readonly envConfig: EnvConfig; - constructor(filePath: string) { + constructor(filePath: string = `${process.env.NODE_ENV || 'development'}.env`) { const config = dotenv.parse(fs.readFileSync(filePath)); this.envConfig = this.validateInput(config); } @@ -22,7 +22,10 @@ export class ConfigService { .valid('development', 'production', 'test', 'provision') .default('development'), PORT: Joi.number().default(3000), - MONGODB_URI: Joi.string().required() + MONGODB_URI: Joi.string().required(), + JWT_SECRET: Joi.string().required(), + IDS_AUTH_URL: Joi.string().required(), + IDS_VALIDATE_URL: Joi.string().required(), }); const { error, value: validatedEnvConfig } = envVarsSchema.validate( @@ -37,4 +40,16 @@ export class ConfigService { get mongodbUri(): string { return String(this.envConfig.MONGODB_URI); } + + get idsAuthUrl(): string { + return String(this.envConfig.IDS_AUTH_URL); + } + + get idsValidatedUrl(): string { + return String(this.envConfig.IDS_VALIDATE_URL); + } + + get jwtSecret(): string { + return String(this.envConfig.JWT_SECRET); + } } \ No newline at end of file diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts deleted file mode 100644 index 61920f1..0000000 --- a/test/app.e2e-spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import * as request from 'supertest'; -import { AppModule } from './../src/app.module'; - -describe('AppController (e2e)', () => { - let app; - - beforeEach(async () => { - const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); - - app = moduleFixture.createNestApplication(); - await app.init(); - }); - - it('/ (GET)', () => { - return request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!'); - }); -}); diff --git a/test/jest-e2e.json b/test/jest-e2e.json deleted file mode 100644 index e9d912f..0000000 --- a/test/jest-e2e.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "moduleFileExtensions": ["js", "json", "ts"], - "rootDir": ".", - "testEnvironment": "node", - "testRegex": ".e2e-spec.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - } -} diff --git a/yarn.lock b/yarn.lock index 2ceb289..4f0a9af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -372,10 +372,21 @@ object-hash "2.0.0" uuid "3.3.3" +"@nestjs/jwt@^6.1.1": + version "6.1.1" + resolved "https://registry.npm.taobao.org/@nestjs/jwt/download/@nestjs/jwt-6.1.1.tgz#78883321fc8663a7cf32aa725a70adc8454bbf5d" + dependencies: + "@types/jsonwebtoken" "7.2.8" + jsonwebtoken "8.4.0" + "@nestjs/mongoose@^6.1.2": version "6.1.2" resolved "https://registry.npm.taobao.org/@nestjs/mongoose/download/@nestjs/mongoose-6.1.2.tgz#fe1c227f5c1fd0f5c9be5c4e37b2897f744bc0b0" +"@nestjs/passport@^6.1.0": + version "6.1.0" + resolved "https://registry.npm.taobao.org/@nestjs/passport/download/@nestjs/passport-6.1.0.tgz#80da326cc976a82530648d8025b04c8e2d41c10e" + "@nestjs/platform-express@^6.7.2": version "6.10.1" resolved "https://registry.npm.taobao.org/@nestjs/platform-express/download/@nestjs/platform-express-6.10.1.tgz#12cfa39e0651048ac7f526c2f1b0f73171af8acb" @@ -438,6 +449,12 @@ version "1.3.1" resolved "https://registry.npm.taobao.org/@types/anymatch/download/@types/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" +"@types/axios@^0.14.0": + version "0.14.0" + resolved "https://registry.npm.taobao.org/@types/axios/download/@types/axios-0.14.0.tgz#ec2300fbe7d7dddd7eb9d3abf87999964cafce46" + dependencies: + axios "*" + "@types/babel__core@^7.1.0": version "7.1.3" resolved "https://registry.npm.taobao.org/@types/babel__core/download/@types/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" @@ -505,7 +522,7 @@ "@types/node" "*" "@types/range-parser" "*" -"@types/express@^4.17.1": +"@types/express@*", "@types/express@^4.17.1": version "4.17.2" resolved "https://registry.npm.taobao.org/@types/express/download/@types/express-4.17.2.tgz#a0fb7a23d8855bac31bc01d5a58cadd9b2173e6c" dependencies: @@ -552,6 +569,18 @@ version "0.0.29" resolved "https://registry.npm.taobao.org/@types/json5/download/@types/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" +"@types/jsonwebtoken@*": + version "8.3.5" + resolved "https://registry.npm.taobao.org/@types/jsonwebtoken/download/@types/jsonwebtoken-8.3.5.tgz#ff9be1151a844095df1ff5f723651298c2c07659" + dependencies: + "@types/node" "*" + +"@types/jsonwebtoken@7.2.8": + version "7.2.8" + resolved "https://registry.npm.taobao.org/@types/jsonwebtoken/download/@types/jsonwebtoken-7.2.8.tgz#8d199dab4ddb5bba3234f8311b804d2027af2b3a" + dependencies: + "@types/node" "*" + "@types/mime@*": version "2.0.1" resolved "https://registry.npm.taobao.org/@types/mime/download/@types/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" @@ -560,10 +589,37 @@ version "3.0.3" resolved "https://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" +"@types/moment@^2.13.0": + version "2.13.0" + resolved "https://registry.npm.taobao.org/@types/moment/download/@types/moment-2.13.0.tgz#604ebd189bc3bc34a1548689404e61a2a4aac896" + dependencies: + moment "*" + "@types/node@*", "@types/node@^12.7.5": version "12.12.12" resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-12.12.12.tgz?cache=0&sync_timestamp=1574471534104&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-12.12.12.tgz#529bc3e73dbb35dd9e90b0a1c83606a9d3264bdb" +"@types/passport-jwt@^3.0.3": + version "3.0.3" + resolved "https://registry.npm.taobao.org/@types/passport-jwt/download/@types/passport-jwt-3.0.3.tgz#47b6c43af668852d7c83e56a23ed9f4515dd1814" + dependencies: + "@types/express" "*" + "@types/jsonwebtoken" "*" + "@types/passport-strategy" "*" + +"@types/passport-strategy@*": + version "0.2.35" + resolved "https://registry.npm.taobao.org/@types/passport-strategy/download/@types/passport-strategy-0.2.35.tgz#e52f5212279ea73f02d9b06af67efe9cefce2d0c" + dependencies: + "@types/express" "*" + "@types/passport" "*" + +"@types/passport@*": + version "1.0.2" + resolved "https://registry.npm.taobao.org/@types/passport/download/@types/passport-1.0.2.tgz#f085033e2b301b1f97d4b57bfa73d8e934650c63" + dependencies: + "@types/express" "*" + "@types/range-parser@*": version "1.2.3" resolved "https://registry.npm.taobao.org/@types/range-parser/download/@types/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" @@ -990,7 +1046,7 @@ aws4@^1.8.0: version "1.8.0" resolved "https://registry.npm.taobao.org/aws4/download/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" -axios@0.19.0: +axios@*, axios@0.19.0, axios@^0.19.0: version "0.19.0" resolved "https://registry.npm.taobao.org/axios/download/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" dependencies: @@ -1211,6 +1267,10 @@ bson@^1.1.1, bson@~1.1.1: version "1.1.3" resolved "https://registry.npm.taobao.org/bson/download/bson-1.1.3.tgz#aa82cb91f9a453aaa060d6209d0675114a8154d3" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.npm.taobao.org/buffer-equal-constant-time/download/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -1834,6 +1894,12 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.npm.taobao.org/ecdsa-sig-formatter/download/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -2173,6 +2239,10 @@ fast-safe-stringify@2.0.7: version "2.0.7" resolved "https://registry.npm.taobao.org/fast-safe-stringify/download/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" +fast-xml-parser@^3.15.0: + version "3.15.0" + resolved "https://registry.npm.taobao.org/fast-xml-parser/download/fast-xml-parser-3.15.0.tgz#0f5b562013482e2dab19b7ffd033621e1d000fa7" + fastq@^1.6.0: version "1.6.0" resolved "https://registry.npm.taobao.org/fastq/download/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2" @@ -3354,6 +3424,35 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonwebtoken@8.4.0: + version "8.4.0" + resolved "https://registry.npm.taobao.org/jsonwebtoken/download/jsonwebtoken-8.4.0.tgz#8757f7b4cb7440d86d5e2f3becefa70536c8e46a" + dependencies: + jws "^3.1.5" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + +jsonwebtoken@^8.2.0: + version "8.5.1" + resolved "https://registry.npm.taobao.org/jsonwebtoken/download/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -3363,6 +3462,21 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.npm.taobao.org/jwa/download/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.1.5, jws@^3.2.2: + version "3.2.2" + resolved "https://registry.npm.taobao.org/jws/download/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + kareem@2.3.1: version "2.3.1" resolved "https://registry.npm.taobao.org/kareem/download/kareem-2.3.1.tgz#def12d9c941017fabfb00f873af95e9c99e1be87" @@ -3434,10 +3548,38 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.npm.taobao.org/lodash.includes/download/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.npm.taobao.org/lodash.isboolean/download/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.npm.taobao.org/lodash.isinteger/download/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.npm.taobao.org/lodash.isnumber/download/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.npm.taobao.org/lodash.isplainobject/download/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.npm.taobao.org/lodash.isstring/download/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.npm.taobao.org/lodash.memoize/download/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.npm.taobao.org/lodash.once/download/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.npm.taobao.org/lodash.sortby/download/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -3695,6 +3837,10 @@ mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1: dependencies: minimist "0.0.8" +moment@*, moment@^2.24.0: + version "2.24.0" + resolved "https://registry.npm.taobao.org/moment/download/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + mongodb@3.3.4: version "3.3.4" resolved "https://registry.npm.taobao.org/mongodb/download/mongodb-3.3.4.tgz#f52eec4a04005101e63715d4d1f67bf784fa0aef" @@ -4173,6 +4319,24 @@ pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.npm.taobao.org/pascalcase/download/pascalcase-0.1.1.tgz?cache=0&sync_timestamp=1565253337239&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpascalcase%2Fdownload%2Fpascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" +passport-jwt@^4.0.0: + version "4.0.0" + resolved "https://registry.npm.taobao.org/passport-jwt/download/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" + dependencies: + jsonwebtoken "^8.2.0" + passport-strategy "^1.0.0" + +passport-strategy@1.x.x, passport-strategy@^1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/passport-strategy/download/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + +passport@^0.4.0: + version "0.4.0" + resolved "https://registry.npm.taobao.org/passport/download/passport-0.4.0.tgz#c5095691347bd5ad3b5e180238c3914d16f05811" + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + path-browserify@0.0.1: version "0.0.1" resolved "https://registry.npm.taobao.org/path-browserify/download/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" @@ -4211,6 +4375,10 @@ path-type@^4.0.0: version "4.0.0" resolved "https://registry.npm.taobao.org/path-type/download/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" +pause@0.0.1: + version "0.0.1" + resolved "https://registry.npm.taobao.org/pause/download/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + pbkdf2@^3.0.3: version "3.0.17" resolved "https://registry.npm.taobao.org/pbkdf2/download/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"