@boarteam/boar-pack-users-backend 5.4.0 → 6.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +23 -20
- package/src/auth/auth-manage.controller.ts +1 -1
- package/src/auth/auth-strategies.constants.ts +2 -0
- package/src/auth/auth.controller.ts +5 -69
- package/src/auth/auth.module.ts +26 -9
- package/src/auth/auth.service.ts +1 -1
- package/src/auth/google/google-auth.config.ts +26 -0
- package/src/auth/google/google-auth.controller.ts +40 -0
- package/src/auth/{google-auth.guard.ts → google/google-auth.guard.ts} +1 -1
- package/src/auth/{google-auth.strategy.ts → google/google-auth.strategy.ts} +2 -2
- package/src/auth/index.ts +10 -10
- package/src/auth/local-auth/local-auth.controller.ts +34 -0
- package/src/auth/{local-auth.guard.ts → local-auth/local-auth.guard.ts} +1 -1
- package/src/auth/{local-auth.strategy.ts → local-auth/local-auth.strategy.ts} +3 -3
- package/src/auth/microsoft/ms-auth.config.ts +29 -0
- package/src/auth/microsoft/ms-auth.controller.ts +40 -0
- package/src/auth/{ms-auth.guard.ts → microsoft/ms-auth.guard.ts} +1 -1
- package/src/auth/{ms-auth.strategy.ts → microsoft/ms-auth.strategy.ts} +3 -3
- package/src/auth/yandex/yandex-auth.config.ts +26 -0
- package/src/auth/yandex/yandex-auth.controller.ts +40 -0
- package/src/auth/yandex/yandex-auth.guard.ts +6 -0
- package/src/auth/yandex/yandex-auth.strategy.ts +59 -0
- package/src/event-logs/entities/event-log.entity.ts +1 -2
- package/src/event-logs/event-logs.controller.ts +1 -13
- package/src/event-logs/event-logs.interceptor.ts +6 -2
- package/src/event-logs/event-logs.middleware.ts +3 -1
- package/src/event-logs/event-logs.module.ts +0 -2
- package/src/event-logs/event-logs.service.ts +9 -47
- package/src/tokens/my-tokens.controller.ts +1 -1
- package/src/tokens/tokens.controller.ts +1 -1
- package/src/tokens/tokens.service.ts +1 -1
- package/src/users/me.controller.ts +1 -1
- package/src/users/users-editing.guard.ts +1 -1
- package/src/users/users.controller.ts +1 -1
- package/src/users/users.service.ts +1 -1
- package/src/auth/google-auth.config.ts +0 -38
- package/src/auth/ms-auth.config.ts +0 -45
- /package/src/auth/{google-auth.filter.ts → auth.exception-filter.ts} +0 -0
- /package/src/auth/{local-auth.dto.ts → local-auth/local-auth.dto.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@boarteam/boar-pack-users-backend",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-alpha.1",
|
|
4
4
|
"description": "NestJS Users module including permissions system, authentication strategies etc",
|
|
5
5
|
"main": "src/index",
|
|
6
6
|
"files": [
|
|
@@ -14,51 +14,54 @@
|
|
|
14
14
|
"access": "public"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@boarteam/boar-pack-common-backend": "^
|
|
18
|
-
"@casl/ability": "^6.7.
|
|
19
|
-
"@
|
|
20
|
-
"@
|
|
21
|
-
"@nestjs/
|
|
22
|
-
"@nestjs/
|
|
23
|
-
"@nestjs/
|
|
24
|
-
"@nestjs/
|
|
25
|
-
"@nestjs/
|
|
26
|
-
"@nestjs/
|
|
27
|
-
"@nestjs/
|
|
17
|
+
"@boarteam/boar-pack-common-backend": "^3.0.0-alpha.0",
|
|
18
|
+
"@casl/ability": "^6.7.3",
|
|
19
|
+
"@dataui/crud": "^5.3.4",
|
|
20
|
+
"@dataui/crud-typeorm": "^5.3.4",
|
|
21
|
+
"@nestjs/common": "^11.0.10",
|
|
22
|
+
"@nestjs/config": "^4.0.0",
|
|
23
|
+
"@nestjs/core": "^11.0.10",
|
|
24
|
+
"@nestjs/jwt": "^11.0.0",
|
|
25
|
+
"@nestjs/passport": "^11.0.5",
|
|
26
|
+
"@nestjs/platform-express": "^11.0.10",
|
|
27
|
+
"@nestjs/schedule": "^5.0.1",
|
|
28
|
+
"@nestjs/swagger": "^11.0.4",
|
|
29
|
+
"@nestjs/typeorm": "^11.0.0",
|
|
28
30
|
"@nestjsx/crud": "^5.0.0-alpha.3",
|
|
29
31
|
"@nestjsx/crud-typeorm": "^5.0.0-alpha.3",
|
|
30
32
|
"bcrypt": "^5.1.1",
|
|
31
|
-
"joi": "^17.
|
|
33
|
+
"joi": "^17.13.3",
|
|
32
34
|
"lodash": "^4.17.21",
|
|
33
35
|
"moment": "^2.30.1",
|
|
34
|
-
"moment-timezone": "^0.5.
|
|
35
|
-
"nestjs-joi": "^1.10.
|
|
36
|
+
"moment-timezone": "^0.5.47",
|
|
37
|
+
"nestjs-joi": "^1.10.1",
|
|
36
38
|
"openapi-typescript-codegen": "^0.29.0",
|
|
37
39
|
"passport": "^0.7.0",
|
|
38
40
|
"passport-http-bearer": "^1.0.1",
|
|
39
41
|
"passport-jwt": "^4.0.1",
|
|
40
42
|
"passport-local": "^1.0.0",
|
|
41
|
-
"pg": "^8.13.
|
|
43
|
+
"pg": "^8.13.3",
|
|
42
44
|
"typeorm": "^0.3.20",
|
|
43
|
-
"ws": "^8.
|
|
45
|
+
"ws": "^8.18.0"
|
|
44
46
|
},
|
|
45
47
|
"devDependencies": {
|
|
46
48
|
"@nestjs/platform-express": "^10.4.15",
|
|
47
49
|
"@types/bcrypt": "^5.0.2",
|
|
48
|
-
"@types/passport-google-oauth20": "^2.0.
|
|
50
|
+
"@types/passport-google-oauth20": "^2.0.16",
|
|
49
51
|
"@types/passport-http-bearer": "^1.0.41",
|
|
50
52
|
"@types/passport-jwt": "^4.0.1",
|
|
51
53
|
"@types/passport-local": "^1.0.38",
|
|
52
|
-
"@types/ws": "^8.5.
|
|
54
|
+
"@types/ws": "^8.5.14",
|
|
53
55
|
"class-transformer": "^0.5.1",
|
|
54
56
|
"openapi-typescript-codegen": "^0.29.0",
|
|
55
57
|
"passport-azure-ad-oauth2": "^0.0.4",
|
|
56
58
|
"passport-google-oauth20": "^2.0.0",
|
|
59
|
+
"passport-yandex": "^0.0.5",
|
|
57
60
|
"pg": "^8.13.1"
|
|
58
61
|
},
|
|
59
62
|
"scripts": {
|
|
60
63
|
"yalc:push": "yalc push",
|
|
61
64
|
"gen-types": "SWAGGER=true JWT_SECRET=swagger nest start"
|
|
62
65
|
},
|
|
63
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "79ab6a32f78e67d21f2cc485ecc165861f5c4b8d"
|
|
64
67
|
}
|
|
@@ -3,7 +3,7 @@ import { AuthService } from './auth.service';
|
|
|
3
3
|
import { tokenName } from './auth.constants';
|
|
4
4
|
import { ApiTags } from '@nestjs/swagger';
|
|
5
5
|
import type { Request, Response } from 'express';
|
|
6
|
-
import { LocalAuthTokenDto } from "./local-auth.dto";
|
|
6
|
+
import { LocalAuthTokenDto } from "./local-auth/local-auth.dto";
|
|
7
7
|
import { CheckPolicies, ManageAllPolicy } from "../casl";
|
|
8
8
|
import { UsersService } from "../users";
|
|
9
9
|
|
|
@@ -1,37 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Controller, Post, Req, Res, UnauthorizedException, UseGuards } from '@nestjs/common';
|
|
2
|
+
import { ApiTags } from '@nestjs/swagger';
|
|
3
|
+
import type { Request, Response } from 'express';
|
|
3
4
|
import { AuthService } from './auth.service';
|
|
4
5
|
import { tokenName } from './auth.constants';
|
|
5
6
|
import { JwtAuthGuard, SkipJWTGuard } from '../jwt-auth/jwt-auth.guard';
|
|
6
7
|
import { SkipPoliciesGuard } from '../casl/policies.guard';
|
|
7
|
-
import {
|
|
8
|
-
import { AuthExceptionFilter } from './google-auth.filter';
|
|
9
|
-
import { ApiExtraModels, ApiTags } from '@nestjs/swagger';
|
|
10
|
-
import type { Request, Response } from 'express';
|
|
11
|
-
import { LocalAuthLoginDto, LocalAuthTokenDto } from "./local-auth.dto";
|
|
12
|
-
import { MSAuthGuard } from "./ms-auth.guard";
|
|
8
|
+
import { LocalAuthTokenDto } from "./local-auth/local-auth.dto";
|
|
13
9
|
|
|
14
10
|
@SkipPoliciesGuard()
|
|
15
11
|
@ApiTags('Authentication')
|
|
16
|
-
@ApiExtraModels(LocalAuthTokenDto)
|
|
17
12
|
@Controller('auth')
|
|
18
13
|
export default class AuthController {
|
|
19
|
-
constructor(private authService: AuthService) {
|
|
20
|
-
|
|
21
|
-
@SkipJWTGuard()
|
|
22
|
-
@UseGuards(LocalAuthGuard)
|
|
23
|
-
@Post('login')
|
|
24
|
-
async login(
|
|
25
|
-
@Req() req: Request,
|
|
26
|
-
@Res({ passthrough: true }) res: Response,
|
|
27
|
-
@Body() body: LocalAuthLoginDto,
|
|
28
|
-
): Promise<LocalAuthTokenDto> {
|
|
29
|
-
if (!req.user) {
|
|
30
|
-
throw new UnauthorizedException(`User is not authorized`);
|
|
31
|
-
}
|
|
32
|
-
const loginResult = await this.authService.login(req.user);
|
|
33
|
-
res.cookie(tokenName, loginResult.accessToken);
|
|
34
|
-
return loginResult;
|
|
14
|
+
constructor(private authService: AuthService) {
|
|
35
15
|
}
|
|
36
16
|
|
|
37
17
|
@Post('token')
|
|
@@ -45,50 +25,6 @@ export default class AuthController {
|
|
|
45
25
|
return this.authService.login(req.user);
|
|
46
26
|
}
|
|
47
27
|
|
|
48
|
-
@SkipJWTGuard()
|
|
49
|
-
@UseGuards(GoogleAuthGuard)
|
|
50
|
-
@Get('google')
|
|
51
|
-
async loginGoogle() {}
|
|
52
|
-
|
|
53
|
-
@SkipJWTGuard()
|
|
54
|
-
@UseGuards(GoogleAuthGuard)
|
|
55
|
-
@UseFilters(AuthExceptionFilter)
|
|
56
|
-
@Get('google/callback')
|
|
57
|
-
async loginGoogleCallback(
|
|
58
|
-
@Req() req: Request,
|
|
59
|
-
@Res({ passthrough: true }) res: Response,
|
|
60
|
-
) {
|
|
61
|
-
if (!req.user) {
|
|
62
|
-
throw new UnauthorizedException(`User is not authorized`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const loginResult = await this.authService.login(req.user);
|
|
66
|
-
res.cookie(tokenName, loginResult.accessToken);
|
|
67
|
-
res.redirect('/');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
@SkipJWTGuard()
|
|
71
|
-
@UseGuards(MSAuthGuard)
|
|
72
|
-
@Get('ms')
|
|
73
|
-
async loginMS() {}
|
|
74
|
-
|
|
75
|
-
@SkipJWTGuard()
|
|
76
|
-
@UseGuards(MSAuthGuard)
|
|
77
|
-
@UseFilters(AuthExceptionFilter)
|
|
78
|
-
@Get('ms/callback')
|
|
79
|
-
async loginMSCallback(
|
|
80
|
-
@Req() req: Request,
|
|
81
|
-
@Res({ passthrough: true }) res: Response,
|
|
82
|
-
) {
|
|
83
|
-
if (!req.user) {
|
|
84
|
-
throw new UnauthorizedException(`User is not authorized`);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const loginResult = await this.authService.login(req.user);
|
|
88
|
-
res.cookie(tokenName, loginResult.accessToken);
|
|
89
|
-
res.redirect('/');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
28
|
@SkipJWTGuard()
|
|
93
29
|
@Post('logout')
|
|
94
30
|
async logout(
|
package/src/auth/auth.module.ts
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
1
|
import { DynamicModule, Module } from '@nestjs/common';
|
|
2
2
|
import { AuthService } from './auth.service';
|
|
3
3
|
import { UsersModule } from '../users/users.module';
|
|
4
|
-
import { LocalAuthStrategy } from './local-auth.strategy';
|
|
4
|
+
import { LocalAuthStrategy } from './local-auth/local-auth.strategy';
|
|
5
5
|
import { PassportModule } from '@nestjs/passport';
|
|
6
6
|
import AuthController from './auth.controller';
|
|
7
7
|
import { ConfigModule } from '@nestjs/config';
|
|
8
|
-
import { GoogleAuthStrategy } from './google-auth.strategy';
|
|
9
|
-
import { GoogleAuthConfigService } from "./google-auth.config";
|
|
10
|
-
import { MSAuthStrategy } from './ms-auth.strategy';
|
|
11
|
-
import { MSAuthConfigService } from "./ms-auth.config";
|
|
8
|
+
import { GoogleAuthStrategy } from './google/google-auth.strategy';
|
|
9
|
+
import { GoogleAuthConfigService } from "./google/google-auth.config";
|
|
10
|
+
import { MSAuthStrategy } from './microsoft/ms-auth.strategy';
|
|
11
|
+
import { MSAuthConfigService } from "./microsoft/ms-auth.config";
|
|
12
12
|
import { JwtAuthModule } from "../jwt-auth/jwt-auth.module";
|
|
13
13
|
import { APP_GUARD } from "@nestjs/core";
|
|
14
14
|
import { JwtAuthGuard } from "../jwt-auth/jwt-auth.guard";
|
|
15
15
|
import AuthManageController from "./auth-manage.controller";
|
|
16
|
+
import GoogleAuthController from "./google/google-auth.controller";
|
|
17
|
+
import MsAuthController from "./microsoft/ms-auth.controller";
|
|
18
|
+
import LocalAuthController from "./local-auth/local-auth.controller";
|
|
19
|
+
import { YandexAuthStrategy } from "./yandex/yandex-auth.strategy";
|
|
20
|
+
import { YandexAuthConfigService } from "./yandex/yandex-auth.config";
|
|
21
|
+
import YandexAuthController from "./yandex/yandex-auth.controller";
|
|
16
22
|
|
|
17
23
|
@Module({})
|
|
18
24
|
export class AuthModule {
|
|
19
25
|
static forRoot(config: {
|
|
20
|
-
googleAuth
|
|
21
|
-
msAuth
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
googleAuth?: boolean,
|
|
27
|
+
msAuth?: boolean,
|
|
28
|
+
yandexAuth?: boolean,
|
|
29
|
+
localAuth?: boolean,
|
|
30
|
+
withControllers?: boolean,
|
|
24
31
|
dataSourceName?: string;
|
|
25
32
|
}): DynamicModule {
|
|
26
33
|
const dynamicModule: DynamicModule = {
|
|
@@ -47,20 +54,30 @@ export class AuthModule {
|
|
|
47
54
|
exports: [],
|
|
48
55
|
};
|
|
49
56
|
|
|
57
|
+
const controllers = [];
|
|
50
58
|
if (config.googleAuth) {
|
|
51
59
|
dynamicModule.providers!.push(GoogleAuthConfigService, GoogleAuthStrategy);
|
|
60
|
+
controllers.push(GoogleAuthController);
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
if (config.msAuth) {
|
|
55
64
|
dynamicModule.providers!.push(MSAuthConfigService, MSAuthStrategy);
|
|
65
|
+
controllers.push(MsAuthController);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (config.yandexAuth) {
|
|
69
|
+
dynamicModule.providers!.push(YandexAuthConfigService, YandexAuthStrategy);
|
|
70
|
+
controllers.push(YandexAuthController);
|
|
56
71
|
}
|
|
57
72
|
|
|
58
73
|
if (config.localAuth) {
|
|
59
74
|
dynamicModule.providers!.push(LocalAuthStrategy);
|
|
75
|
+
controllers.push(LocalAuthController);
|
|
60
76
|
}
|
|
61
77
|
|
|
62
78
|
if (config.withControllers) {
|
|
63
79
|
dynamicModule.controllers = [
|
|
80
|
+
...controllers,
|
|
64
81
|
AuthController,
|
|
65
82
|
AuthManageController,
|
|
66
83
|
];
|
package/src/auth/auth.service.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
|
|
|
2
2
|
import { TUser, UsersService } from '../users';
|
|
3
3
|
import { JWTAuthService, TJWTPayload } from '../jwt-auth';
|
|
4
4
|
import bcrypt from 'bcrypt';
|
|
5
|
-
import { LocalAuthTokenDto } from "./local-auth.dto";
|
|
5
|
+
import { LocalAuthTokenDto } from "./local-auth/local-auth.dto";
|
|
6
6
|
|
|
7
7
|
declare global {
|
|
8
8
|
namespace Express {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { ConfigService } from '@nestjs/config';
|
|
3
|
+
|
|
4
|
+
export type TGoogleAuthConfig = {
|
|
5
|
+
clientId: string;
|
|
6
|
+
clientSecret: string;
|
|
7
|
+
callbackURL: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
@Injectable()
|
|
11
|
+
export class GoogleAuthConfigService {
|
|
12
|
+
constructor(private configService: ConfigService) {
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get config(): TGoogleAuthConfig {
|
|
16
|
+
const clientId = this.configService.getOrThrow<string>('GOOGLE_CLIENT_ID');
|
|
17
|
+
const clientSecret = this.configService.getOrThrow<string>('GOOGLE_SECRET_ID');
|
|
18
|
+
const callbackURL = this.configService.getOrThrow<string>('GOOGLE_CALLBACK_URL');
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
clientId,
|
|
22
|
+
clientSecret,
|
|
23
|
+
callbackURL,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Controller, Get, Req, Res, UnauthorizedException, UseFilters, UseGuards } from '@nestjs/common';
|
|
2
|
+
import { ApiTags } from '@nestjs/swagger';
|
|
3
|
+
import type { Request, Response } from 'express';
|
|
4
|
+
import { AuthService } from '../auth.service';
|
|
5
|
+
import { tokenName } from '../auth.constants';
|
|
6
|
+
import { SkipJWTGuard } from '../../jwt-auth/jwt-auth.guard';
|
|
7
|
+
import { SkipPoliciesGuard } from '../../casl/policies.guard';
|
|
8
|
+
import { GoogleAuthGuard } from './google-auth.guard';
|
|
9
|
+
import { AuthExceptionFilter } from '../auth.exception-filter';
|
|
10
|
+
|
|
11
|
+
@SkipPoliciesGuard()
|
|
12
|
+
@ApiTags('Authentication')
|
|
13
|
+
@Controller('auth/google')
|
|
14
|
+
export default class GoogleAuthController {
|
|
15
|
+
constructor(private authService: AuthService) {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@SkipJWTGuard()
|
|
19
|
+
@UseGuards(GoogleAuthGuard)
|
|
20
|
+
@Get('')
|
|
21
|
+
async loginGoogle() {
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@SkipJWTGuard()
|
|
25
|
+
@UseGuards(GoogleAuthGuard)
|
|
26
|
+
@UseFilters(AuthExceptionFilter)
|
|
27
|
+
@Get('callback')
|
|
28
|
+
async loginGoogleCallback(
|
|
29
|
+
@Req() req: Request,
|
|
30
|
+
@Res({ passthrough: true }) res: Response,
|
|
31
|
+
) {
|
|
32
|
+
if (!req.user) {
|
|
33
|
+
throw new UnauthorizedException(`User is not authorized`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const loginResult = await this.authService.login(req.user);
|
|
37
|
+
res.cookie(tokenName, loginResult.accessToken);
|
|
38
|
+
res.redirect('/');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Injectable } from '@nestjs/common';
|
|
2
2
|
import { AuthGuard } from '@nestjs/passport';
|
|
3
|
-
import { GOOGLE_AUTH } from '
|
|
3
|
+
import { GOOGLE_AUTH } from '../auth-strategies.constants';
|
|
4
4
|
|
|
5
5
|
@Injectable()
|
|
6
6
|
export class GoogleAuthGuard extends AuthGuard(GOOGLE_AUTH) {}
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
Logger,
|
|
7
7
|
UnauthorizedException,
|
|
8
8
|
} from '@nestjs/common';
|
|
9
|
-
import { AuthService } from '
|
|
10
|
-
import { GOOGLE_AUTH } from '
|
|
9
|
+
import { AuthService } from '../auth.service';
|
|
10
|
+
import { GOOGLE_AUTH } from '../auth-strategies.constants';
|
|
11
11
|
import { GoogleAuthConfigService } from "./google-auth.config";
|
|
12
12
|
|
|
13
13
|
@Injectable()
|
package/src/auth/index.ts
CHANGED
|
@@ -3,13 +3,13 @@ export * from './auth.controller';
|
|
|
3
3
|
export * from './auth.module';
|
|
4
4
|
export * from './auth.service';
|
|
5
5
|
export * from './auth-strategies.constants';
|
|
6
|
-
export * from './google-auth.config';
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './google-auth.guard';
|
|
9
|
-
export * from './google-auth.strategy';
|
|
10
|
-
export * from './local-auth.dto';
|
|
11
|
-
export * from './local-auth.guard';
|
|
12
|
-
export * from './local-auth.strategy';
|
|
13
|
-
export * from './ms-auth.config';
|
|
14
|
-
export * from './ms-auth.guard';
|
|
15
|
-
export * from './ms-auth.strategy';
|
|
6
|
+
export * from './google/google-auth.config';
|
|
7
|
+
export * from './auth.exception-filter';
|
|
8
|
+
export * from './google/google-auth.guard';
|
|
9
|
+
export * from './google/google-auth.strategy';
|
|
10
|
+
export * from './local-auth/local-auth.dto';
|
|
11
|
+
export * from './local-auth/local-auth.guard';
|
|
12
|
+
export * from './local-auth/local-auth.strategy';
|
|
13
|
+
export * from './microsoft/ms-auth.config';
|
|
14
|
+
export * from './microsoft/ms-auth.guard';
|
|
15
|
+
export * from './microsoft/ms-auth.strategy';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Body, Controller, Post, Req, Res, UnauthorizedException, UseGuards } from '@nestjs/common';
|
|
2
|
+
import { ApiExtraModels, ApiTags } from '@nestjs/swagger';
|
|
3
|
+
import type { Request, Response } from 'express';
|
|
4
|
+
import { LocalAuthGuard } from './local-auth.guard';
|
|
5
|
+
import { AuthService } from '../auth.service';
|
|
6
|
+
import { tokenName } from '../auth.constants';
|
|
7
|
+
import { SkipJWTGuard } from '../../jwt-auth/jwt-auth.guard';
|
|
8
|
+
import { SkipPoliciesGuard } from '../../casl/policies.guard';
|
|
9
|
+
import { LocalAuthLoginDto, LocalAuthTokenDto } from "./local-auth.dto";
|
|
10
|
+
|
|
11
|
+
@SkipPoliciesGuard()
|
|
12
|
+
@ApiTags('Authentication')
|
|
13
|
+
@ApiExtraModels(LocalAuthTokenDto)
|
|
14
|
+
@Controller('auth')
|
|
15
|
+
export default class LocalAuthController {
|
|
16
|
+
constructor(private authService: AuthService) {
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@SkipJWTGuard()
|
|
20
|
+
@UseGuards(LocalAuthGuard)
|
|
21
|
+
@Post('login')
|
|
22
|
+
async login(
|
|
23
|
+
@Req() req: Request,
|
|
24
|
+
@Res({ passthrough: true }) res: Response,
|
|
25
|
+
@Body() body: LocalAuthLoginDto,
|
|
26
|
+
): Promise<LocalAuthTokenDto> {
|
|
27
|
+
if (!req.user) {
|
|
28
|
+
throw new UnauthorizedException(`User is not authorized`);
|
|
29
|
+
}
|
|
30
|
+
const loginResult = await this.authService.login(req.user);
|
|
31
|
+
res.cookie(tokenName, loginResult.accessToken);
|
|
32
|
+
return loginResult;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Injectable } from '@nestjs/common';
|
|
2
2
|
import { AuthGuard } from '@nestjs/passport';
|
|
3
|
-
import { LOCAL_AUTH } from '
|
|
3
|
+
import { LOCAL_AUTH } from '../auth-strategies.constants';
|
|
4
4
|
|
|
5
5
|
@Injectable()
|
|
6
6
|
export class LocalAuthGuard extends AuthGuard(LOCAL_AUTH) {}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Strategy } from 'passport-local';
|
|
2
2
|
import { PassportStrategy } from '@nestjs/passport';
|
|
3
3
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
|
4
|
-
import { AuthService } from '
|
|
5
|
-
import { TUser } from '
|
|
6
|
-
import { LOCAL_AUTH } from '
|
|
4
|
+
import { AuthService } from '../auth.service';
|
|
5
|
+
import { TUser } from '../../users';
|
|
6
|
+
import { LOCAL_AUTH } from '../auth-strategies.constants';
|
|
7
7
|
|
|
8
8
|
@Injectable()
|
|
9
9
|
export class LocalAuthStrategy extends PassportStrategy(Strategy, LOCAL_AUTH) {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { ConfigService } from '@nestjs/config';
|
|
3
|
+
|
|
4
|
+
export type TMSAuthConfig = {
|
|
5
|
+
clientId: string;
|
|
6
|
+
tenantId: string;
|
|
7
|
+
clientSecret: string;
|
|
8
|
+
callbackURL: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
@Injectable()
|
|
12
|
+
export class MSAuthConfigService {
|
|
13
|
+
constructor(private configService: ConfigService) {
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get config(): TMSAuthConfig {
|
|
17
|
+
const clientId = this.configService.getOrThrow<string>('MICROSOFT_CLIENT_ID');
|
|
18
|
+
const tenantId = this.configService.getOrThrow<string>('MICROSOFT_TENANT_ID');
|
|
19
|
+
const clientSecret = this.configService.getOrThrow<string>('MICROSOFT_SECRET_ID');
|
|
20
|
+
const callbackURL = this.configService.getOrThrow<string>('MICROSOFT_CALLBACK_URL');
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
clientId,
|
|
24
|
+
tenantId,
|
|
25
|
+
clientSecret,
|
|
26
|
+
callbackURL,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Controller, Get, Req, Res, UnauthorizedException, UseFilters, UseGuards } from '@nestjs/common';
|
|
2
|
+
import { ApiTags } from '@nestjs/swagger';
|
|
3
|
+
import type { Request, Response } from 'express';
|
|
4
|
+
import { AuthService } from '../auth.service';
|
|
5
|
+
import { tokenName } from '../auth.constants';
|
|
6
|
+
import { SkipJWTGuard } from '../../jwt-auth/jwt-auth.guard';
|
|
7
|
+
import { SkipPoliciesGuard } from '../../casl/policies.guard';
|
|
8
|
+
import { AuthExceptionFilter } from '../auth.exception-filter';
|
|
9
|
+
import { MSAuthGuard } from "./ms-auth.guard";
|
|
10
|
+
|
|
11
|
+
@SkipPoliciesGuard()
|
|
12
|
+
@ApiTags('Authentication')
|
|
13
|
+
@Controller('auth/ms')
|
|
14
|
+
export default class MsAuthController {
|
|
15
|
+
constructor(private authService: AuthService) {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@SkipJWTGuard()
|
|
19
|
+
@UseGuards(MSAuthGuard)
|
|
20
|
+
@Get('')
|
|
21
|
+
async loginMS() {
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@SkipJWTGuard()
|
|
25
|
+
@UseGuards(MSAuthGuard)
|
|
26
|
+
@UseFilters(AuthExceptionFilter)
|
|
27
|
+
@Get('callback')
|
|
28
|
+
async loginMSCallback(
|
|
29
|
+
@Req() req: Request,
|
|
30
|
+
@Res({ passthrough: true }) res: Response,
|
|
31
|
+
) {
|
|
32
|
+
if (!req.user) {
|
|
33
|
+
throw new UnauthorizedException(`User is not authorized`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const loginResult = await this.authService.login(req.user);
|
|
37
|
+
res.cookie(tokenName, loginResult.accessToken);
|
|
38
|
+
res.redirect('/');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Injectable } from '@nestjs/common';
|
|
2
2
|
import { AuthGuard } from '@nestjs/passport';
|
|
3
|
-
import { MS_AUTH } from '
|
|
3
|
+
import { MS_AUTH } from '../auth-strategies.constants';
|
|
4
4
|
|
|
5
5
|
@Injectable()
|
|
6
6
|
export class MSAuthGuard extends AuthGuard(MS_AUTH) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PassportStrategy } from '@nestjs/passport';
|
|
2
2
|
import { Injectable, InternalServerErrorException, Logger, UnauthorizedException, } from '@nestjs/common';
|
|
3
|
-
import { AuthService } from '
|
|
4
|
-
import { MS_AUTH } from '
|
|
3
|
+
import { AuthService } from '../auth.service';
|
|
4
|
+
import { MS_AUTH } from '../auth-strategies.constants';
|
|
5
5
|
import { MSAuthConfigService } from "./ms-auth.config";
|
|
6
|
-
import { JWTAuthService } from "
|
|
6
|
+
import { JWTAuthService } from "../../jwt-auth/jwt-auth.service";
|
|
7
7
|
|
|
8
8
|
// @ts-ignore-next-line There are no types for this package
|
|
9
9
|
import { Strategy, VerifyCallback } from 'passport-azure-ad-oauth2';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { ConfigService } from '@nestjs/config';
|
|
3
|
+
|
|
4
|
+
export type TYandexAuthConfig = {
|
|
5
|
+
clientId: string;
|
|
6
|
+
clientSecret: string;
|
|
7
|
+
callbackURL: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
@Injectable()
|
|
11
|
+
export class YandexAuthConfigService {
|
|
12
|
+
constructor(private configService: ConfigService) {
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get config(): TYandexAuthConfig {
|
|
16
|
+
const clientId = this.configService.getOrThrow<string>('YANDEX_CLIENT_ID');
|
|
17
|
+
const clientSecret = this.configService.getOrThrow<string>('YANDEX_SECRET_ID');
|
|
18
|
+
const callbackURL = this.configService.getOrThrow<string>('YANDEX_CALLBACK_URL');
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
clientId,
|
|
22
|
+
clientSecret,
|
|
23
|
+
callbackURL,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Controller, Get, Req, Res, UnauthorizedException, UseFilters, UseGuards } from '@nestjs/common';
|
|
2
|
+
import { ApiTags } from '@nestjs/swagger';
|
|
3
|
+
import type { Request, Response } from 'express';
|
|
4
|
+
import { AuthService } from '../auth.service';
|
|
5
|
+
import { tokenName } from '../auth.constants';
|
|
6
|
+
import { SkipJWTGuard } from '../../jwt-auth/jwt-auth.guard';
|
|
7
|
+
import { SkipPoliciesGuard } from '../../casl/policies.guard';
|
|
8
|
+
import { YandexAuthGuard } from './yandex-auth.guard';
|
|
9
|
+
import { AuthExceptionFilter } from '../auth.exception-filter';
|
|
10
|
+
|
|
11
|
+
@SkipPoliciesGuard()
|
|
12
|
+
@ApiTags('Authentication')
|
|
13
|
+
@Controller('auth/yandex')
|
|
14
|
+
export default class YandexAuthController {
|
|
15
|
+
constructor(private authService: AuthService) {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@SkipJWTGuard()
|
|
19
|
+
@UseGuards(YandexAuthGuard)
|
|
20
|
+
@Get('')
|
|
21
|
+
async loginYandex() {
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@SkipJWTGuard()
|
|
25
|
+
@UseGuards(YandexAuthGuard)
|
|
26
|
+
@UseFilters(AuthExceptionFilter)
|
|
27
|
+
@Get('callback')
|
|
28
|
+
async loginYandexCallback(
|
|
29
|
+
@Req() req: Request,
|
|
30
|
+
@Res({ passthrough: true }) res: Response,
|
|
31
|
+
) {
|
|
32
|
+
if (!req.user) {
|
|
33
|
+
throw new UnauthorizedException(`User is not authorized`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const loginResult = await this.authService.login(req.user);
|
|
37
|
+
res.cookie(tokenName, loginResult.accessToken);
|
|
38
|
+
res.redirect('/');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Strategy } from 'passport-yandex';
|
|
2
|
+
import { PassportStrategy } from '@nestjs/passport';
|
|
3
|
+
import {
|
|
4
|
+
Injectable,
|
|
5
|
+
InternalServerErrorException,
|
|
6
|
+
Logger,
|
|
7
|
+
UnauthorizedException,
|
|
8
|
+
} from '@nestjs/common';
|
|
9
|
+
import { AuthService } from '../auth.service';
|
|
10
|
+
import { YANDEX_AUTH } from '../auth-strategies.constants';
|
|
11
|
+
import { YandexAuthConfigService } from "./yandex-auth.config";
|
|
12
|
+
import { TUser } from "../../users";
|
|
13
|
+
|
|
14
|
+
@Injectable()
|
|
15
|
+
export class YandexAuthStrategy extends PassportStrategy(
|
|
16
|
+
Strategy,
|
|
17
|
+
YANDEX_AUTH,
|
|
18
|
+
) {
|
|
19
|
+
private readonly logger = new Logger(YandexAuthStrategy.name);
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
private authService: AuthService,
|
|
23
|
+
private yandexAuthConfigService: YandexAuthConfigService,
|
|
24
|
+
) {
|
|
25
|
+
const config = yandexAuthConfigService.config;
|
|
26
|
+
super({
|
|
27
|
+
clientID: config.clientId,
|
|
28
|
+
clientSecret: config.clientSecret,
|
|
29
|
+
callbackURL: config.callbackURL,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async validate(
|
|
34
|
+
accessToken: string,
|
|
35
|
+
refreshToken: string,
|
|
36
|
+
profile: { emails: { value: string; verified: boolean }[] },
|
|
37
|
+
callback: (error: Error | null, user?: TUser | null) => void,
|
|
38
|
+
): Promise<any> {
|
|
39
|
+
try {
|
|
40
|
+
const user = await this.authService.validateUserByEmail(
|
|
41
|
+
profile.emails[0].value,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
if (!user) {
|
|
45
|
+
callback(new UnauthorizedException('User is not found'));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
callback(null, user);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
this.logger.error(e, e.stack);
|
|
52
|
+
callback(
|
|
53
|
+
new InternalServerErrorException(
|
|
54
|
+
'Impossible to log in user via yandex',
|
|
55
|
+
),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Column, CreateDateColumn, Entity,
|
|
1
|
+
import { Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm';
|
|
2
2
|
import { User } from "../../users";
|
|
3
3
|
|
|
4
4
|
export enum LogType {
|
|
@@ -113,7 +113,6 @@ export class EventLog {
|
|
|
113
113
|
})
|
|
114
114
|
statusCode: number | null;
|
|
115
115
|
|
|
116
|
-
@Index()
|
|
117
116
|
@Column({
|
|
118
117
|
default: 'main'
|
|
119
118
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Controller, Get, Query } from '@nestjs/common';
|
|
2
2
|
import { ApiExtraModels, ApiOkResponse, ApiTags, getSchemaPath } from '@nestjs/swagger';
|
|
3
|
-
import { Crud, CrudController } from '@
|
|
3
|
+
import { Crud, CrudController } from '@dataui/crud';
|
|
4
4
|
import { EventLogsService } from './event-logs.service';
|
|
5
5
|
import { EventLog } from './entities/event-log.entity';
|
|
6
6
|
import { EventLogCreateDto } from './dto/event-log-create.dto';
|
|
@@ -65,16 +65,4 @@ export class EventLogsController implements CrudController<EventLog>{
|
|
|
65
65
|
const end = query.endTime ? new Date(query.endTime) : undefined;
|
|
66
66
|
return this.service.getTimeline(start, end, query.timezone);
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
@CheckPolicies(new ViewEventLogsPolicy())
|
|
70
|
-
@Get('service-names')
|
|
71
|
-
@ApiOkResponse({
|
|
72
|
-
schema: {
|
|
73
|
-
type: 'array',
|
|
74
|
-
items: { type: 'string' },
|
|
75
|
-
},
|
|
76
|
-
})
|
|
77
|
-
async getServiceNames(): Promise<string[]> {
|
|
78
|
-
return this.service.getServiceNames();
|
|
79
|
-
}
|
|
80
68
|
}
|
|
@@ -57,13 +57,17 @@ export class EventLogInterceptor implements NestInterceptor {
|
|
|
57
57
|
logEntry.duration = Date.now() - now;
|
|
58
58
|
logEntry.statusCode = response.statusCode;
|
|
59
59
|
logEntry.logLevel = response.statusCode >= 500 ? LogLevel.ERROR : (response.statusCode >= 400 ? LogLevel.WARNING : LogLevel.INFO);
|
|
60
|
-
this.eventLogService.audit(logEntry, request)
|
|
60
|
+
this.eventLogService.audit(logEntry, request).catch((error) => {
|
|
61
|
+
this.logger.error(`Failed to log event: ${error.message}`);
|
|
62
|
+
});
|
|
61
63
|
}),
|
|
62
64
|
catchError((error: HttpException) => {
|
|
63
65
|
logEntry.duration = Date.now() - now;
|
|
64
66
|
logEntry.statusCode = error?.getStatus?.() || 500;
|
|
65
67
|
logEntry.logLevel = logEntry.statusCode >= 500 ? LogLevel.ERROR : LogLevel.WARNING;
|
|
66
|
-
this.eventLogService.audit(logEntry, request)
|
|
68
|
+
this.eventLogService.audit(logEntry, request).catch((error) => {
|
|
69
|
+
this.logger.error(`Failed to log event: ${error.message}`);
|
|
70
|
+
});
|
|
67
71
|
return throwError(() => error);
|
|
68
72
|
}),
|
|
69
73
|
);
|
|
@@ -50,7 +50,9 @@ export class EventLogMiddleware implements NestMiddleware {
|
|
|
50
50
|
? LogLevel.WARNING
|
|
51
51
|
: LogLevel.INFO;
|
|
52
52
|
|
|
53
|
-
this.eventLogService.audit(logEntry, req)
|
|
53
|
+
this.eventLogService.audit(logEntry, req).catch((error) => {
|
|
54
|
+
this.logger.error(`Failed to log event: ${error.message}`);
|
|
55
|
+
});
|
|
54
56
|
});
|
|
55
57
|
|
|
56
58
|
next();
|
|
@@ -12,7 +12,6 @@ import { CONFIGURE_EVENTS_MIDDLEWARE, SERVICE_CONFIG_TOKEN } from "./event-logs.
|
|
|
12
12
|
import { TEventLogServiceConfig } from "./event-logs.types";
|
|
13
13
|
import { EventLogsLogger } from "./event-logs.logger";
|
|
14
14
|
import { EventLogMiddleware } from "./event-logs.middleware";
|
|
15
|
-
import { ScheduleModule } from "@nestjs/schedule";
|
|
16
15
|
|
|
17
16
|
@Module({})
|
|
18
17
|
export class EventLogsModule implements NestModule {
|
|
@@ -50,7 +49,6 @@ export class EventLogsModule implements NestModule {
|
|
|
50
49
|
module: EventLogsModule,
|
|
51
50
|
imports: [
|
|
52
51
|
CaslModule.forFeature(),
|
|
53
|
-
ScheduleModule.forRoot(),
|
|
54
52
|
TypeOrmModule.forFeature([EventLog], config.dataSourceName),
|
|
55
53
|
],
|
|
56
54
|
providers: [
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Injectable, Logger } from '@nestjs/common';
|
|
2
|
-
import { TypeOrmCrudService } from '@
|
|
2
|
+
import { TypeOrmCrudService } from '@dataui/crud-typeorm';
|
|
3
3
|
import { EventLog, LogLevel, LogType, UserRole } from './entities/event-log.entity';
|
|
4
4
|
import { DataSource, Repository } from 'typeorm';
|
|
5
5
|
import { Request } from 'express';
|
|
6
6
|
import { Roles } from "../users";
|
|
7
7
|
import { EventLogTimelineDto } from "./dto/event-log-timeline.dto";
|
|
8
|
-
import { Cron, CronExpression } from "@nestjs/schedule";
|
|
9
8
|
import moment from "moment";
|
|
10
9
|
import 'moment-timezone';
|
|
11
10
|
|
|
@@ -14,7 +13,6 @@ type TInterval = 'second' | 'minute' | 'hour' | 'day' | 'week';
|
|
|
14
13
|
@Injectable()
|
|
15
14
|
export class EventLogsService extends TypeOrmCrudService<EventLog> {
|
|
16
15
|
private static requestHandled = Symbol('requestHandled');
|
|
17
|
-
private logsStore: Partial<EventLog>[] = [];
|
|
18
16
|
|
|
19
17
|
private readonly logger = new Logger(EventLogsService.name);
|
|
20
18
|
|
|
@@ -30,37 +28,7 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
|
|
|
30
28
|
super(repo);
|
|
31
29
|
}
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
private async saveAccumulatedLogs(): Promise<void> {
|
|
35
|
-
if (this.logsStore.length > 0) {
|
|
36
|
-
const logs = [...this.logsStore];
|
|
37
|
-
this.logger.verbose('Reset event logs store variable');
|
|
38
|
-
this.logsStore = [];
|
|
39
|
-
|
|
40
|
-
await this.repo.save(logs).catch(e => {
|
|
41
|
-
// DO NOT USE LOGGER HERE - it will cause infinite loop
|
|
42
|
-
console.error('Error while saving logs');
|
|
43
|
-
console.error(e);
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@Cron(CronExpression.EVERY_WEEK)
|
|
49
|
-
private async deleteOldEventLogs() {
|
|
50
|
-
const threeMonthsAgo = new Date();
|
|
51
|
-
threeMonthsAgo.setMonth(threeMonthsAgo.getMonth() - 2);
|
|
52
|
-
|
|
53
|
-
const result = await this.repo
|
|
54
|
-
.createQueryBuilder()
|
|
55
|
-
.delete()
|
|
56
|
-
.from(EventLog)
|
|
57
|
-
.where('created_at <= :threeMonthsAgo', { threeMonthsAgo })
|
|
58
|
-
.execute();
|
|
59
|
-
|
|
60
|
-
this.logger.debug(`Removed ${result.affected} expired records from event_logs table.`);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
audit(eventLog: Partial<EventLog>, request?: Request): void {
|
|
31
|
+
async audit(eventLog: Partial<EventLog>, request?: Request): Promise<void> {
|
|
64
32
|
// @ts-ignore
|
|
65
33
|
if (request?.[EventLogsService.requestHandled]) {
|
|
66
34
|
this.logger.debug('Request already handled');
|
|
@@ -86,7 +54,7 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
|
|
|
86
54
|
request[EventLogsService.requestHandled] = true;
|
|
87
55
|
}
|
|
88
56
|
|
|
89
|
-
this.
|
|
57
|
+
await this.repo.save({
|
|
90
58
|
...logPartial,
|
|
91
59
|
...eventLog,
|
|
92
60
|
logType: LogType.AUDIT,
|
|
@@ -98,9 +66,8 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
|
|
|
98
66
|
return request?.[EventLogsService.requestHandled];
|
|
99
67
|
}
|
|
100
68
|
|
|
101
|
-
// TODO: Remove async in the next major version (breaking change)
|
|
102
69
|
async operationalLog(eventLog: Partial<EventLog>): Promise<void> {
|
|
103
|
-
this.
|
|
70
|
+
await this.repo.save({
|
|
104
71
|
logLevel: LogLevel.INFO,
|
|
105
72
|
userRole: UserRole.SYSTEM,
|
|
106
73
|
...eventLog,
|
|
@@ -109,11 +76,15 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
|
|
|
109
76
|
}
|
|
110
77
|
|
|
111
78
|
public applicationLog(eventLog: Partial<EventLog>): void {
|
|
112
|
-
this.
|
|
79
|
+
this.repo.save({
|
|
113
80
|
logLevel: LogLevel.INFO,
|
|
114
81
|
userRole: UserRole.SYSTEM,
|
|
115
82
|
...eventLog,
|
|
116
83
|
logType: LogType.APPLICATION,
|
|
84
|
+
}).catch(e => {
|
|
85
|
+
// DO NOT USE LOGGER HERE - it will cause infinite loop
|
|
86
|
+
console.error('Error while saving application log');
|
|
87
|
+
console.error(e);
|
|
117
88
|
});
|
|
118
89
|
}
|
|
119
90
|
|
|
@@ -163,15 +134,6 @@ export class EventLogsService extends TypeOrmCrudService<EventLog> {
|
|
|
163
134
|
]);
|
|
164
135
|
}
|
|
165
136
|
|
|
166
|
-
async getServiceNames(): Promise<string[]> {
|
|
167
|
-
const result = await this.repo
|
|
168
|
-
.createQueryBuilder('event_logs')
|
|
169
|
-
.select('event_logs.service')
|
|
170
|
-
.distinctOn(['service'])
|
|
171
|
-
.getMany();
|
|
172
|
-
return result.map((data) => data.service);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
137
|
private async getOldestLogDate(): Promise<Date> {
|
|
176
138
|
const oldestLog = await this.repo.createQueryBuilder('event_log')
|
|
177
139
|
.select('MIN(event_log.createdAt)', 'min')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Body, Controller, Req } from '@nestjs/common';
|
|
2
2
|
import { ApiTags } from '@nestjs/swagger';
|
|
3
|
-
import { Crud, CrudAuth, CrudController, type CrudRequest, Override, ParsedRequest } from '@
|
|
3
|
+
import { Crud, CrudAuth, CrudController, type CrudRequest, Override, ParsedRequest } from '@dataui/crud';
|
|
4
4
|
import { TokensService } from './tokens.service';
|
|
5
5
|
import { Token } from './entities/token.entity';
|
|
6
6
|
import { ManageMyTokensPolicy } from "./policies/manage-my-tokens.policy";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Controller } from '@nestjs/common';
|
|
2
2
|
import { ApiTags } from '@nestjs/swagger';
|
|
3
|
-
import { Crud, CrudController } from '@
|
|
3
|
+
import { Crud, CrudController } from '@dataui/crud';
|
|
4
4
|
import { TokensService } from './tokens.service';
|
|
5
5
|
import { Token } from './entities/token.entity';
|
|
6
6
|
import { TokenUpdateDto } from "./dto/token-update.dto";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Crud, CrudAuth, CrudController, type CrudRequest, Override, ParsedRequest, } from '@
|
|
1
|
+
import { Crud, CrudAuth, CrudController, type CrudRequest, Override, ParsedRequest, } from '@dataui/crud';
|
|
2
2
|
import { TUser, User } from './entities/user.entity';
|
|
3
3
|
import { Controller, Req } from '@nestjs/common';
|
|
4
4
|
import type { Request } from 'express';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Controller, UseFilters, UseGuards } from '@nestjs/common';
|
|
2
2
|
import { UsersService } from './users.service';
|
|
3
|
-
import { Crud } from '@
|
|
3
|
+
import { Crud } from '@dataui/crud';
|
|
4
4
|
import { User } from './entities/user.entity';
|
|
5
5
|
import { CheckPolicies, ManageAllPolicy } from '../casl';
|
|
6
6
|
import { UserCreateDto } from './dto/user-create.dto';
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { ConfigService } from '@nestjs/config';
|
|
3
|
-
|
|
4
|
-
export type TGoogleAuthConfig = {
|
|
5
|
-
clientId: string;
|
|
6
|
-
clientSecret: string;
|
|
7
|
-
callbackURL: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
@Injectable()
|
|
11
|
-
export class GoogleAuthConfigService {
|
|
12
|
-
constructor(private configService: ConfigService) {
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
get config(): TGoogleAuthConfig {
|
|
16
|
-
const clientId = this.configService.get<string>('GOOGLE_CLIENT_ID');
|
|
17
|
-
const clientSecret = this.configService.get<string>('GOOGLE_SECRET_ID');
|
|
18
|
-
const callbackURL = this.configService.get<string>('GOOGLE_CALLBACK_URL');
|
|
19
|
-
|
|
20
|
-
if (!clientId) {
|
|
21
|
-
throw new Error('GOOGLE_CLIENT_ID is not defined');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (!clientSecret) {
|
|
25
|
-
throw new Error('GOOGLE_SECRET_ID is not defined');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!callbackURL) {
|
|
29
|
-
throw new Error('GOOGLE_CALLBACK_URL is not defined');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
clientId,
|
|
34
|
-
clientSecret,
|
|
35
|
-
callbackURL,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { ConfigService } from '@nestjs/config';
|
|
3
|
-
|
|
4
|
-
export type TMSAuthConfig = {
|
|
5
|
-
clientId: string;
|
|
6
|
-
tenantId: string;
|
|
7
|
-
clientSecret: string;
|
|
8
|
-
callbackURL: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
@Injectable()
|
|
12
|
-
export class MSAuthConfigService {
|
|
13
|
-
constructor(private configService: ConfigService) {
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
get config(): TMSAuthConfig {
|
|
17
|
-
const clientId = this.configService.get<string>('MICROSOFT_CLIENT_ID');
|
|
18
|
-
const tenantId = this.configService.get<string>('MICROSOFT_TENANT_ID');
|
|
19
|
-
const clientSecret = this.configService.get<string>('MICROSOFT_SECRET_ID');
|
|
20
|
-
const callbackURL = this.configService.get<string>('MICROSOFT_CALLBACK_URL');
|
|
21
|
-
|
|
22
|
-
if (!clientId) {
|
|
23
|
-
throw new Error('MICROSOFT_CLIENT_ID is not defined');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (!tenantId) {
|
|
27
|
-
throw new Error('MICROSOFT_TENANT_ID is not defined');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!clientSecret) {
|
|
31
|
-
throw new Error('MICROSOFT_SECRET_ID is not defined');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!callbackURL) {
|
|
35
|
-
throw new Error('MICROSOFT_CALLBACK_URL is not defined');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
clientId,
|
|
40
|
-
tenantId,
|
|
41
|
-
clientSecret,
|
|
42
|
-
callbackURL,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
}
|
|
File without changes
|
|
File without changes
|