feat: 添加鉴权相关功能。

This commit is contained in:
Ivan Li 2021-07-17 17:32:42 +08:00
parent 51d5ac6ee6
commit d0f6b8f9a6
6 changed files with 230 additions and 1 deletions

View File

@ -14,5 +14,8 @@ db:
port: 6379
password:
prefix: blog
etcd:
hosts:
- 'http://192.168.31.194:2379'
workspaces:
root: '/Users/ivanli/Projects/fennec/workspaces'

209
package-lock.json generated
View File

@ -8,6 +8,7 @@
"version": "0.0.1",
"license": "UNLICENSED",
"dependencies": {
"@nestjs-lib/auth": "^0.1.1",
"@nestjs/bull": "^0.3.1",
"@nestjs/common": "^7.6.15",
"@nestjs/config": "^0.6.2",
@ -28,6 +29,7 @@
"ioredis": "^4.25.0",
"js-yaml": "^4.0.0",
"marked": "^2.1.3",
"nestjs-etcd": "^0.2.0",
"nestjs-redis": "^1.2.8",
"observable-to-async-generator": "^1.0.1-rc",
"pg": "^8.5.1",
@ -2058,6 +2060,31 @@
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
}
},
"node_modules/@grpc/grpc-js": {
"version": "1.3.5",
"resolved": "https://npm.ivanli.cc/@grpc%2fgrpc-js/-/grpc-js-1.3.5.tgz",
"integrity": "sha512-V29L2QNKkLWM3bcJfVFMSo+Z7kkO8A1s7MAfdzBXLYEC1PE5/M0n1iXBDiD5aUtyVLh5GILcbme2bGtIHl0FMQ==",
"license": "Apache-2.0",
"dependencies": {
"@types/node": ">=12.12.47"
},
"engines": {
"node": "^8.13.0 || >=10.10.0"
}
},
"node_modules/@grpc/proto-loader": {
"version": "0.5.6",
"resolved": "https://npm.ivanli.cc/@grpc%2fproto-loader/-/proto-loader-0.5.6.tgz",
"integrity": "sha512-DT14xgw3PSzPxwS13auTEwxhMMOoz33DPUKNtmYK/QYbBSpLXJy78FGGs5yVoxVobEqPm4iW9MOIoz0A3bLTRQ==",
"license": "Apache-2.0",
"dependencies": {
"lodash.camelcase": "^4.3.0",
"protobufjs": "^6.8.6"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@ -2476,6 +2503,18 @@
"node-pre-gyp": "bin/node-pre-gyp"
}
},
"node_modules/@nestjs-lib/auth": {
"version": "0.1.1",
"resolved": "https://npm.ivanli.cc/@nestjs-lib%2fauth/-/auth-0.1.1.tgz",
"integrity": "sha512-fYje3oHErN/1ZKyrzTlZ+3+w7fp3XplkKz26U9OycTA5hu+/LlM6EEvuMt7pfdo02KllVtcUWMtmKbezzr4Ujw==",
"license": "MIT",
"peerDependencies": {
"@nestjs/common": "^7.0.0",
"@nestjs/graphql": "^7.10.3",
"jose": "^3.14.0",
"nestjs-etcd": "^0.2.0"
}
},
"node_modules/@nestjs/bull": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@nestjs/bull/-/bull-0.3.1.tgz",
@ -4923,6 +4962,15 @@
"node": "*"
}
},
"node_modules/bignumber.js": {
"version": "9.0.1",
"resolved": "https://npm.ivanli.cc/bignumber.js/-/bignumber.js-9.0.1.tgz",
"integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -5713,6 +5761,15 @@
"node": ">= 0.12.0"
}
},
"node_modules/cockatiel": {
"version": "1.1.1",
"resolved": "https://npm.ivanli.cc/cockatiel/-/cockatiel-1.1.1.tgz",
"integrity": "sha512-YO02ZhTcK2HOZodksWfg4tS1GYYt1j7R6U1unAkwcQf1uoIYKSBqPrfqXlLNbsyMvkDXMwa2nuwZDHbUkB1VbQ==",
"license": "MIT",
"engines": {
"node": ">=10 <11 || >=12"
}
},
"node_modules/code-block-writer": {
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz",
@ -6866,6 +6923,18 @@
"node": ">= 0.6"
}
},
"node_modules/etcd3": {
"version": "1.1.0",
"resolved": "https://npm.ivanli.cc/etcd3/-/etcd3-1.1.0.tgz",
"integrity": "sha512-9SnJvaPyW5IYdJHJWX91CYo1QZCAev2B7PxrQWIe2tGbutZOmsXHfjNDKwEltFWoG5h++K3/JfWPjJdOGX90hg==",
"license": "MIT",
"dependencies": {
"@grpc/grpc-js": "^1.1.7",
"@grpc/proto-loader": "^0.5.5",
"bignumber.js": "^9.0.0",
"cockatiel": "^1.1.1"
}
},
"node_modules/eventemitter3": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
@ -9795,6 +9864,16 @@
"node": ">= 10.13.0"
}
},
"node_modules/jose": {
"version": "3.14.0",
"resolved": "https://npm.ivanli.cc/jose/-/jose-3.14.0.tgz",
"integrity": "sha512-Hk4yFVGiSTuryL0XVyRTCvCPoD9eDCvEX/t+SpHTXXeNXsoxyopPLhoCLTt90vnu7yeIYXDdJWHNgI3Ix4H1FQ==",
"license": "MIT",
"peer": true,
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -10079,6 +10158,12 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.camelcase": {
"version": "4.3.0",
"resolved": "https://npm.ivanli.cc/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
"integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
"license": "MIT"
},
"node_modules/lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
@ -10723,6 +10808,21 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
"node_modules/nestjs-etcd": {
"version": "0.2.0",
"resolved": "https://npm.ivanli.cc/nestjs-etcd/-/nestjs-etcd-0.2.0.tgz",
"integrity": "sha512-I5tekNGFJ97auyHeCrnCN38D5AkaxxUAx3PlaZA0EOO/BTyNfyw9Fzqs4McCoUakT/sVVwdGELulcofRUzaFpw==",
"license": "MIT",
"dependencies": {
"etcd3": "^1.1.0"
},
"peerDependencies": {
"@nestjs/common": "^6.7.0 || ^7.0.0",
"@nestjs/core": "^6.7.0 || ^7.0.0",
"reflect-metadata": "^0.1.12",
"rxjs": "^6.0.0"
}
},
"node_modules/nestjs-redis": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/nestjs-redis/-/nestjs-redis-1.3.3.tgz",
@ -11763,6 +11863,32 @@
"react-is": "^16.8.1"
}
},
"node_modules/protobufjs": {
"version": "6.11.2",
"resolved": "https://npm.ivanli.cc/protobufjs/-/protobufjs-6.11.2.tgz",
"integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==",
"hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
"@protobufjs/codegen": "^2.0.4",
"@protobufjs/eventemitter": "^1.1.0",
"@protobufjs/fetch": "^1.1.0",
"@protobufjs/float": "^1.0.2",
"@protobufjs/inquire": "^1.1.0",
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.0",
"@types/long": "^4.0.1",
"@types/node": ">=13.7.0",
"long": "^4.0.0"
},
"bin": {
"pbjs": "bin/pbjs",
"pbts": "bin/pbts"
}
},
"node_modules/proxy-addr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
@ -17246,6 +17372,23 @@
"integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg==",
"requires": {}
},
"@grpc/grpc-js": {
"version": "1.3.5",
"resolved": "https://npm.ivanli.cc/@grpc%2fgrpc-js/-/grpc-js-1.3.5.tgz",
"integrity": "sha512-V29L2QNKkLWM3bcJfVFMSo+Z7kkO8A1s7MAfdzBXLYEC1PE5/M0n1iXBDiD5aUtyVLh5GILcbme2bGtIHl0FMQ==",
"requires": {
"@types/node": ">=12.12.47"
}
},
"@grpc/proto-loader": {
"version": "0.5.6",
"resolved": "https://npm.ivanli.cc/@grpc%2fproto-loader/-/proto-loader-0.5.6.tgz",
"integrity": "sha512-DT14xgw3PSzPxwS13auTEwxhMMOoz33DPUKNtmYK/QYbBSpLXJy78FGGs5yVoxVobEqPm4iW9MOIoz0A3bLTRQ==",
"requires": {
"lodash.camelcase": "^4.3.0",
"protobufjs": "^6.8.6"
}
},
"@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@ -17592,6 +17735,12 @@
"tar": "^6.1.0"
}
},
"@nestjs-lib/auth": {
"version": "0.1.1",
"resolved": "https://npm.ivanli.cc/@nestjs-lib%2fauth/-/auth-0.1.1.tgz",
"integrity": "sha512-fYje3oHErN/1ZKyrzTlZ+3+w7fp3XplkKz26U9OycTA5hu+/LlM6EEvuMt7pfdo02KllVtcUWMtmKbezzr4Ujw==",
"requires": {}
},
"@nestjs/bull": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@nestjs/bull/-/bull-0.3.1.tgz",
@ -19516,6 +19665,11 @@
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true
},
"bignumber.js": {
"version": "9.0.1",
"resolved": "https://npm.ivanli.cc/bignumber.js/-/bignumber.js-9.0.1.tgz",
"integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA=="
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -20131,6 +20285,11 @@
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
"dev": true
},
"cockatiel": {
"version": "1.1.1",
"resolved": "https://npm.ivanli.cc/cockatiel/-/cockatiel-1.1.1.tgz",
"integrity": "sha512-YO02ZhTcK2HOZodksWfg4tS1GYYt1j7R6U1unAkwcQf1uoIYKSBqPrfqXlLNbsyMvkDXMwa2nuwZDHbUkB1VbQ=="
},
"code-block-writer": {
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz",
@ -21016,6 +21175,17 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"etcd3": {
"version": "1.1.0",
"resolved": "https://npm.ivanli.cc/etcd3/-/etcd3-1.1.0.tgz",
"integrity": "sha512-9SnJvaPyW5IYdJHJWX91CYo1QZCAev2B7PxrQWIe2tGbutZOmsXHfjNDKwEltFWoG5h++K3/JfWPjJdOGX90hg==",
"requires": {
"@grpc/grpc-js": "^1.1.7",
"@grpc/proto-loader": "^0.5.5",
"bignumber.js": "^9.0.0",
"cockatiel": "^1.1.1"
}
},
"eventemitter3": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
@ -23248,6 +23418,12 @@
"supports-color": "^7.0.0"
}
},
"jose": {
"version": "3.14.0",
"resolved": "https://npm.ivanli.cc/jose/-/jose-3.14.0.tgz",
"integrity": "sha512-Hk4yFVGiSTuryL0XVyRTCvCPoD9eDCvEX/t+SpHTXXeNXsoxyopPLhoCLTt90vnu7yeIYXDdJWHNgI3Ix4H1FQ==",
"peer": true
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -23462,6 +23638,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lodash.camelcase": {
"version": "4.3.0",
"resolved": "https://npm.ivanli.cc/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
"integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
},
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
@ -23965,6 +24146,14 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
"nestjs-etcd": {
"version": "0.2.0",
"resolved": "https://npm.ivanli.cc/nestjs-etcd/-/nestjs-etcd-0.2.0.tgz",
"integrity": "sha512-I5tekNGFJ97auyHeCrnCN38D5AkaxxUAx3PlaZA0EOO/BTyNfyw9Fzqs4McCoUakT/sVVwdGELulcofRUzaFpw==",
"requires": {
"etcd3": "^1.1.0"
}
},
"nestjs-redis": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/nestjs-redis/-/nestjs-redis-1.3.3.tgz",
@ -24757,6 +24946,26 @@
"react-is": "^16.8.1"
}
},
"protobufjs": {
"version": "6.11.2",
"resolved": "https://npm.ivanli.cc/protobufjs/-/protobufjs-6.11.2.tgz",
"integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==",
"requires": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
"@protobufjs/codegen": "^2.0.4",
"@protobufjs/eventemitter": "^1.1.0",
"@protobufjs/fetch": "^1.1.0",
"@protobufjs/float": "^1.0.2",
"@protobufjs/inquire": "^1.1.0",
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.0",
"@types/long": "^4.0.1",
"@types/node": ">=13.7.0",
"long": "^4.0.0"
}
},
"proxy-addr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",

View File

@ -21,6 +21,7 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs-lib/auth": "^0.1.1",
"@nestjs/bull": "^0.3.1",
"@nestjs/common": "^7.6.15",
"@nestjs/config": "^0.6.2",
@ -41,6 +42,7 @@
"ioredis": "^4.25.0",
"js-yaml": "^4.0.0",
"marked": "^2.1.3",
"nestjs-etcd": "^0.2.0",
"nestjs-redis": "^1.2.8",
"observable-to-async-generator": "^1.0.1-rc",
"pg": "^8.5.1",

View File

@ -11,6 +11,8 @@ import { ParseBodyMiddleware } from './commons/middleware/parse-body.middleware'
import { BullModule } from '@nestjs/bull';
import { PubSubModule } from './commons/pub-sub/pub-sub.module';
import { ArticlesModule } from './articles/articles.module';
import { EtcdModule } from 'nestjs-etcd';
import { CommonsModule } from './commons/commons.module';
@Module({
imports: [
@ -73,6 +75,14 @@ import { ArticlesModule } from './articles/articles.module';
}),
inject: [ConfigService],
}),
EtcdModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
hosts: configService.get<string>('db.etcd.hosts', 'localhost:2379'),
}),
inject: [ConfigService],
}),
CommonsModule,
ArticlesModule,
],
controllers: [AppController],

View File

@ -13,11 +13,13 @@ import { CreateArticleInput } from './dto/create-article.input';
import { UpdateArticleInput } from './dto/update-article.input';
import * as marked from 'marked';
import { getLanguage, highlight } from 'highlight.js';
import { AccountRole, Roles } from '@nestjs-lib/auth';
@Resolver(() => Article)
export class ArticlesResolver {
constructor(private readonly articlesService: ArticlesService) {}
@Roles(AccountRole.admin, AccountRole.super)
@Mutation(() => Article)
createArticle(
@Args('createArticleInput') createArticleInput: CreateArticleInput,
@ -35,6 +37,7 @@ export class ArticlesResolver {
return this.articlesService.findOne(id);
}
@Roles(AccountRole.admin, AccountRole.super)
@Mutation(() => Article)
async updateArticle(
@Args('updateArticleInput') updateArticleInput: UpdateArticleInput,
@ -43,6 +46,7 @@ export class ArticlesResolver {
return this.articlesService.update(article, updateArticleInput);
}
@Roles(AccountRole.admin, AccountRole.super)
@Mutation(() => Int)
removeArticle(@Args('id', { type: () => String }) id: string) {
return this.articlesService.remove(id);

View File

@ -1,10 +1,11 @@
import { Module } from '@nestjs/common';
import { PasswordConverter } from './services/password-converter';
import { PubSubModule } from './pub-sub/pub-sub.module';
import { AuthModule } from '@nestjs-lib/auth';
@Module({
imports: [PubSubModule, AuthModule],
providers: [PasswordConverter],
exports: [PasswordConverter],
imports: [PubSubModule],
})
export class CommonsModule {}