@boarteam/boar-pack-users-backend 8.0.0 → 8.1.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/dist/audit-logs/audit-logs.controller.js +2 -0
- package/dist/audit-logs/audit-logs.controller.js.map +1 -1
- package/dist/audit-logs/entities/audit-log.entity.js +4 -0
- package/dist/audit-logs/entities/audit-log.entity.js.map +1 -1
- package/dist/auth/auth-manage.controller.js +2 -0
- package/dist/auth/auth-manage.controller.js.map +1 -1
- package/dist/auth/auth.controller.js +4 -0
- package/dist/auth/auth.controller.js.map +1 -1
- package/dist/auth/google/google-auth.controller.js +3 -0
- package/dist/auth/google/google-auth.controller.js.map +1 -1
- package/dist/auth/local-auth/local-auth.controller.js +2 -0
- package/dist/auth/local-auth/local-auth.controller.js.map +1 -1
- package/dist/auth/local-auth/local-auth.dto.js +7 -0
- package/dist/auth/local-auth/local-auth.dto.js.map +1 -1
- package/dist/auth/microsoft/ms-auth.controller.js +3 -0
- package/dist/auth/microsoft/ms-auth.controller.js.map +1 -1
- package/dist/auth/yandex/yandex-auth.controller.js +3 -0
- package/dist/auth/yandex/yandex-auth.controller.js.map +1 -1
- package/dist/event-logs/dto/event-log-create.dto.js +4 -0
- package/dist/event-logs/dto/event-log-create.dto.js.map +1 -1
- package/dist/event-logs/dto/event-log-timeline-query.dto.js +4 -0
- package/dist/event-logs/dto/event-log-timeline-query.dto.js.map +1 -1
- package/dist/event-logs/dto/event-log-timeline.dto.js +4 -0
- package/dist/event-logs/dto/event-log-timeline.dto.js.map +1 -1
- package/dist/event-logs/dto/event-log-update.dto.js +4 -0
- package/dist/event-logs/dto/event-log-update.dto.js.map +1 -1
- package/dist/event-logs/entities/event-log.entity.js +4 -0
- package/dist/event-logs/entities/event-log.entity.js.map +1 -1
- package/dist/event-logs/event-logs.controller.js +3 -0
- package/dist/event-logs/event-logs.controller.js.map +1 -1
- package/dist/event-logs/event-logs.logger.d.ts +2 -2
- package/dist/event-logs/event-logs.logger.js +2 -2
- package/dist/event-logs/event-logs.logger.js.map +1 -1
- package/dist/revoked-tokens/entities/revoked-token.entity.js +4 -0
- package/dist/revoked-tokens/entities/revoked-token.entity.js.map +1 -1
- package/dist/settings/dto/event-settings.dto.js +4 -0
- package/dist/settings/dto/event-settings.dto.js.map +1 -1
- package/dist/settings/entities/setting.entity.js +4 -0
- package/dist/settings/entities/setting.entity.js.map +1 -1
- package/dist/settings/settings.controller.js +3 -0
- package/dist/settings/settings.controller.js.map +1 -1
- package/dist/telegraf/dto/telegram-settings-update.dto.js +4 -0
- package/dist/telegraf/dto/telegram-settings-update.dto.js.map +1 -1
- package/dist/telegraf/dto/telegram-settings.dto.js +4 -0
- package/dist/telegraf/dto/telegram-settings.dto.js.map +1 -1
- package/dist/telegraf/telegraf.controller.js +4 -0
- package/dist/telegraf/telegraf.controller.js.map +1 -1
- package/dist/tokens/dto/token-create.dto.js +4 -0
- package/dist/tokens/dto/token-create.dto.js.map +1 -1
- package/dist/tokens/dto/token-update.dto.js +4 -0
- package/dist/tokens/dto/token-update.dto.js.map +1 -1
- package/dist/tokens/dto/token-with-value.dto.js +4 -0
- package/dist/tokens/dto/token-with-value.dto.js.map +1 -1
- package/dist/tokens/entities/token.entity.js +4 -0
- package/dist/tokens/entities/token.entity.js.map +1 -1
- package/dist/tokens/my-tokens.controller.js +2 -0
- package/dist/tokens/my-tokens.controller.js.map +1 -1
- package/dist/tokens/tokens.controller.js +1 -0
- package/dist/tokens/tokens.controller.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/users/dto/permission.dto.js +4 -0
- package/dist/users/dto/permission.dto.js.map +1 -1
- package/dist/users/dto/user-create.dto.js +4 -0
- package/dist/users/dto/user-create.dto.js.map +1 -1
- package/dist/users/dto/user-update.dto.js +4 -0
- package/dist/users/dto/user-update.dto.js.map +1 -1
- package/dist/users/entities/user.entity.js +4 -0
- package/dist/users/entities/user.entity.js.map +1 -1
- package/dist/users/me.controller.js +2 -0
- package/dist/users/me.controller.js.map +1 -1
- package/dist/users/users.controller.js +1 -0
- package/dist/users/users.controller.js.map +1 -1
- package/dist/ws-auth/ws-auth.guard.js +2 -2
- package/dist/ws-auth/ws-auth.guard.js.map +1 -1
- package/package.json +5 -5
- package/src/audit-logs/audit-log-base-service.ts +0 -169
- package/src/audit-logs/audit-logs.controller.ts +0 -74
- package/src/audit-logs/audit-logs.module.ts +0 -49
- package/src/audit-logs/audit-logs.permissions.ts +0 -4
- package/src/audit-logs/audit-logs.service.ts +0 -14
- package/src/audit-logs/audit-logs.types.ts +0 -9
- package/src/audit-logs/entities/audit-log.entity.ts +0 -46
- package/src/audit-logs/policies/view-audit-logs.policy.ts +0 -8
- package/src/auth/auth-manage.controller.ts +0 -35
- package/src/auth/auth-strategies.constants.ts +0 -7
- package/src/auth/auth.config.ts +0 -20
- package/src/auth/auth.constants.ts +0 -2
- package/src/auth/auth.controller.ts +0 -54
- package/src/auth/auth.exception-filter.ts +0 -15
- package/src/auth/auth.module.ts +0 -118
- package/src/auth/auth.service.ts +0 -122
- package/src/auth/google/google-auth.config.ts +0 -26
- package/src/auth/google/google-auth.controller.ts +0 -39
- package/src/auth/google/google-auth.guard.ts +0 -6
- package/src/auth/google/google-auth.strategy.ts +0 -59
- package/src/auth/index.ts +0 -15
- package/src/auth/local-auth/local-auth.controller.ts +0 -37
- package/src/auth/local-auth/local-auth.dto.ts +0 -17
- package/src/auth/local-auth/local-auth.guard.ts +0 -6
- package/src/auth/local-auth/local-auth.strategy.ts +0 -21
- package/src/auth/microsoft/ms-auth.config.ts +0 -29
- package/src/auth/microsoft/ms-auth.controller.ts +0 -40
- package/src/auth/microsoft/ms-auth.guard.ts +0 -8
- package/src/auth/microsoft/ms-auth.strategy.ts +0 -63
- package/src/auth/yandex/yandex-auth.config.ts +0 -26
- package/src/auth/yandex/yandex-auth.controller.ts +0 -39
- package/src/auth/yandex/yandex-auth.guard.ts +0 -6
- package/src/auth/yandex/yandex-auth.strategy.ts +0 -59
- package/src/bcrypt/bcrypt.config.ts +0 -27
- package/src/bcrypt/bcrypt.module.ts +0 -19
- package/src/bcrypt/bcrypt.service.ts +0 -24
- package/src/bcrypt/index.ts +0 -3
- package/src/casl/action.enum.ts +0 -7
- package/src/casl/casl-ability.factory.ts +0 -130
- package/src/casl/casl.module.ts +0 -31
- package/src/casl/fields-permission.interceptor.ts +0 -58
- package/src/casl/index.ts +0 -5
- package/src/casl/policies/manage-all.policy.ts +0 -9
- package/src/casl/policies.guard.ts +0 -80
- package/src/event-logs/dto/event-log-create.dto.ts +0 -47
- package/src/event-logs/dto/event-log-timeline-query.dto.ts +0 -13
- package/src/event-logs/dto/event-log-timeline.dto.ts +0 -9
- package/src/event-logs/dto/event-log-update.dto.ts +0 -47
- package/src/event-logs/entities/event-log.entity.ts +0 -140
- package/src/event-logs/event-logs.constants.ts +0 -2
- package/src/event-logs/event-logs.controller.ts +0 -80
- package/src/event-logs/event-logs.interceptor.ts +0 -75
- package/src/event-logs/event-logs.logger.ts +0 -48
- package/src/event-logs/event-logs.middleware.ts +0 -58
- package/src/event-logs/event-logs.module.ts +0 -131
- package/src/event-logs/event-logs.permissions.ts +0 -4
- package/src/event-logs/event-logs.service.ts +0 -236
- package/src/event-logs/event-logs.types.ts +0 -4
- package/src/event-logs/index.ts +0 -10
- package/src/event-logs/policies/manage-event-logs.policy.ts +0 -8
- package/src/event-logs/policies/view-event-logs.policy.ts +0 -8
- package/src/generateTypes.ts +0 -94
- package/src/index.ts +0 -10
- package/src/jwt-auth/index.ts +0 -5
- package/src/jwt-auth/jwt-auth.config.ts +0 -27
- package/src/jwt-auth/jwt-auth.guard.ts +0 -26
- package/src/jwt-auth/jwt-auth.module.ts +0 -64
- package/src/jwt-auth/jwt-auth.refresh.guard.ts +0 -7
- package/src/jwt-auth/jwt-auth.refresh.srtategy.ts +0 -85
- package/src/jwt-auth/jwt-auth.service.ts +0 -59
- package/src/jwt-auth/jwt-auth.srtategy.ts +0 -83
- package/src/revoked-tokens/entities/revoked-token.entity.ts +0 -50
- package/src/revoked-tokens/index.ts +0 -3
- package/src/revoked-tokens/revoked-tokens.module.ts +0 -29
- package/src/revoked-tokens/revoked-tokens.service.ts +0 -88
- package/src/settings/dto/event-settings.dto.ts +0 -3
- package/src/settings/entities/setting.entity.ts +0 -19
- package/src/settings/index.ts +0 -5
- package/src/settings/policies/manage-settings.policy.ts +0 -8
- package/src/settings/settings.constants.ts +0 -9
- package/src/settings/settings.controller.ts +0 -32
- package/src/settings/settings.module.ts +0 -46
- package/src/settings/settings.permissions.ts +0 -3
- package/src/settings/settings.service.ts +0 -51
- package/src/telegraf/dto/telegram-settings-update.dto.ts +0 -13
- package/src/telegraf/dto/telegram-settings.dto.ts +0 -5
- package/src/telegraf/index.ts +0 -3
- package/src/telegraf/telegraf.constants.ts +0 -5
- package/src/telegraf/telegraf.controller.ts +0 -40
- package/src/telegraf/telegraf.module.ts +0 -28
- package/src/telegraf/telegraf.service.ts +0 -110
- package/src/tokens/dto/token-create.dto.ts +0 -7
- package/src/tokens/dto/token-update.dto.ts +0 -7
- package/src/tokens/dto/token-with-value.dto.ts +0 -8
- package/src/tokens/entities/token.entity.ts +0 -26
- package/src/tokens/index.ts +0 -2
- package/src/tokens/my-tokens.controller.ts +0 -82
- package/src/tokens/policies/manage-my-tokens.policy.ts +0 -9
- package/src/tokens/policies/manage-tokens.policy.ts +0 -8
- package/src/tokens/policies/view-tokens.policy.ts +0 -8
- package/src/tokens/tokens-auth.guard.ts +0 -7
- package/src/tokens/tokens-auth.strategy.ts +0 -48
- package/src/tokens/tokens.constants.ts +0 -1
- package/src/tokens/tokens.controller.ts +0 -45
- package/src/tokens/tokens.module.ts +0 -86
- package/src/tokens/tokens.permissions.ts +0 -5
- package/src/tokens/tokens.service.ts +0 -14
- package/src/users/dto/permission.dto.ts +0 -5
- package/src/users/dto/user-create.dto.ts +0 -37
- package/src/users/dto/user-update.dto.ts +0 -37
- package/src/users/entities/permissions.ts +0 -23
- package/src/users/entities/user.entity.ts +0 -67
- package/src/users/hash-password.interceptor.ts +0 -22
- package/src/users/index.ts +0 -13
- package/src/users/me.controller.ts +0 -63
- package/src/users/policies/manage-users.policy.ts +0 -10
- package/src/users/policies/view-users.policy.ts +0 -10
- package/src/users/users-editing.guard.ts +0 -85
- package/src/users/users.config.ts +0 -27
- package/src/users/users.constants.ts +0 -1
- package/src/users/users.controller.ts +0 -85
- package/src/users/users.module.ts +0 -81
- package/src/users/users.service.ts +0 -23
- package/src/ws-auth/index.ts +0 -3
- package/src/ws-auth/ws-auth.constants.ts +0 -2
- package/src/ws-auth/ws-auth.d2 +0 -14
- package/src/ws-auth/ws-auth.gateway.ts +0 -25
- package/src/ws-auth/ws-auth.guard.ts +0 -28
- package/src/ws-auth/ws-auth.module.ts +0 -36
- package/src/ws-auth/ws-auth.service.ts +0 -108
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { ExtractJwt, Strategy } from 'passport-jwt';
|
|
2
|
-
import { PassportStrategy } from '@nestjs/passport';
|
|
3
|
-
import { Injectable, Logger, UnauthorizedException } from '@nestjs/common';
|
|
4
|
-
import { JWTAuthConfigService } from './jwt-auth.config';
|
|
5
|
-
import { Request } from 'express';
|
|
6
|
-
import { JWT_AUTH, tokenName } from '../auth';
|
|
7
|
-
import { UsersService } from '../users';
|
|
8
|
-
import { RevokedTokensService } from '../revoked-tokens';
|
|
9
|
-
|
|
10
|
-
export type TJWTPayload = {
|
|
11
|
-
email: string;
|
|
12
|
-
sub: string;
|
|
13
|
-
iat?: string; // Issued At
|
|
14
|
-
exp?: number; // Expiration Time
|
|
15
|
-
jti?: string; // JWT ID, used for revocation
|
|
16
|
-
sid?: string; // Session ID to identify the family of tokens
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type TJWTRefreshPayload = {
|
|
20
|
-
sub: string; // User ID
|
|
21
|
-
jti?: string; // JWT ID, used for revocation
|
|
22
|
-
iat?: number; // Issued At
|
|
23
|
-
exp?: number; // Expiration Time
|
|
24
|
-
sid?: string; // Session ID to identify the family of tokens
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
@Injectable()
|
|
28
|
-
export class JwtAuthStrategy extends PassportStrategy(Strategy, JWT_AUTH) {
|
|
29
|
-
private readonly logger = new Logger(JwtAuthStrategy.name);
|
|
30
|
-
constructor(
|
|
31
|
-
private usersService: UsersService,
|
|
32
|
-
private jwtAuthConfigService: JWTAuthConfigService,
|
|
33
|
-
private revokedTokensService: RevokedTokensService,
|
|
34
|
-
) {
|
|
35
|
-
super({
|
|
36
|
-
jwtFromRequest: ExtractJwt.fromExtractors([
|
|
37
|
-
ExtractJwt.fromAuthHeaderAsBearerToken(),
|
|
38
|
-
(req: Request) => {
|
|
39
|
-
const cookies = req.headers.cookie?.split('; ');
|
|
40
|
-
if (!cookies) {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const cookie = cookies.find(c => c.startsWith(`${tokenName}=`));
|
|
45
|
-
if (!cookie) {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return cookie.split('=')[1];
|
|
50
|
-
},
|
|
51
|
-
]),
|
|
52
|
-
ignoreExpiration: false,
|
|
53
|
-
secretOrKey: jwtAuthConfigService.config.jwtSecret,
|
|
54
|
-
passReqToCallback: true,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async validate(req: Request, payload: TJWTPayload) {
|
|
59
|
-
this.logger.debug(`Validating user with email: ${payload.email}`);
|
|
60
|
-
|
|
61
|
-
// Check if a token has been revoked
|
|
62
|
-
if (payload.jti) {
|
|
63
|
-
const isRevoked = await this.revokedTokensService.isTokenRevoked(payload.jti, payload.sid);
|
|
64
|
-
if (isRevoked) {
|
|
65
|
-
this.logger.debug(`Token with JTI ${payload.jti} has been revoked`);
|
|
66
|
-
throw new UnauthorizedException('Token has been revoked');
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const userId = payload.sub;
|
|
71
|
-
const user = await this.usersService.findOne({
|
|
72
|
-
select: ['id', 'email', 'role', 'permissions'],
|
|
73
|
-
where: { id: userId },
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
if (!user) {
|
|
77
|
-
throw new UnauthorizedException();
|
|
78
|
-
}
|
|
79
|
-
req.jwt = payload; // Attach JWT payload to the request for further use
|
|
80
|
-
|
|
81
|
-
return user;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
|
2
|
-
|
|
3
|
-
export enum TOKEN_TYPE {
|
|
4
|
-
ACCESS = 'access',
|
|
5
|
-
REFRESH = 'refresh',
|
|
6
|
-
SESSION = 'session',
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
@Entity('revoked_tokens')
|
|
10
|
-
@Index('IDX_REVOKED_TOKEN_SID_TYPE', ['sid', 'tokenType'])
|
|
11
|
-
export class RevokedToken {
|
|
12
|
-
@PrimaryGeneratedColumn('uuid')
|
|
13
|
-
id: string;
|
|
14
|
-
|
|
15
|
-
@Column({
|
|
16
|
-
unique: true,
|
|
17
|
-
type: 'uuid',
|
|
18
|
-
})
|
|
19
|
-
@Index('IDX_REVOKED_TOKEN_JTI')
|
|
20
|
-
jti: string;
|
|
21
|
-
|
|
22
|
-
@Column({
|
|
23
|
-
type: 'uuid',
|
|
24
|
-
nullable: true,
|
|
25
|
-
default: null,
|
|
26
|
-
})
|
|
27
|
-
sid: string | null;
|
|
28
|
-
|
|
29
|
-
@Column({
|
|
30
|
-
type: 'enum',
|
|
31
|
-
enum: TOKEN_TYPE,
|
|
32
|
-
default: TOKEN_TYPE.ACCESS,
|
|
33
|
-
})
|
|
34
|
-
tokenType: TOKEN_TYPE;
|
|
35
|
-
|
|
36
|
-
@Column({
|
|
37
|
-
name: 'expires_at',
|
|
38
|
-
type: 'timestamp with time zone',
|
|
39
|
-
})
|
|
40
|
-
@Index('IDX_REVOKED_TOKEN_EXPIRES_AT')
|
|
41
|
-
expiresAt: Date;
|
|
42
|
-
|
|
43
|
-
@CreateDateColumn({
|
|
44
|
-
name: 'created_at',
|
|
45
|
-
type: 'timestamp with time zone',
|
|
46
|
-
})
|
|
47
|
-
createdAt: Date;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export type TRevokedToken = Omit<RevokedToken, 'id' | 'createdAt'>;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { Module } from '@nestjs/common';
|
|
2
|
-
import { TypeOrmModule, getDataSourceToken } from '@nestjs/typeorm';
|
|
3
|
-
import { RevokedToken } from './entities/revoked-token.entity';
|
|
4
|
-
import { RevokedTokensService } from './revoked-tokens.service';
|
|
5
|
-
import { DataSource } from 'typeorm';
|
|
6
|
-
import { ScheduleModule } from "@nestjs/schedule";
|
|
7
|
-
|
|
8
|
-
@Module({})
|
|
9
|
-
export class RevokedTokensModule {
|
|
10
|
-
static register(config: { dataSourceName?: string } = {}) {
|
|
11
|
-
return {
|
|
12
|
-
module: RevokedTokensModule,
|
|
13
|
-
imports: [
|
|
14
|
-
TypeOrmModule.forFeature([RevokedToken], config.dataSourceName),
|
|
15
|
-
ScheduleModule.forRoot(),
|
|
16
|
-
],
|
|
17
|
-
providers: [
|
|
18
|
-
{
|
|
19
|
-
provide: RevokedTokensService,
|
|
20
|
-
inject: [getDataSourceToken(config.dataSourceName)],
|
|
21
|
-
useFactory: (dataSource: DataSource) => {
|
|
22
|
-
return new RevokedTokensService(dataSource.getRepository(RevokedToken));
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
exports: [RevokedTokensService],
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { Injectable, Logger } from '@nestjs/common';
|
|
2
|
-
import { Repository } from 'typeorm';
|
|
3
|
-
import { RevokedToken, TOKEN_TYPE, TRevokedToken } from './entities/revoked-token.entity';
|
|
4
|
-
import { Cron, CronExpression } from "@nestjs/schedule";
|
|
5
|
-
import ms, { StringValue } from "ms";
|
|
6
|
-
import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere";
|
|
7
|
-
|
|
8
|
-
@Injectable()
|
|
9
|
-
export class RevokedTokensService {
|
|
10
|
-
private readonly logger = new Logger(RevokedTokensService.name);
|
|
11
|
-
|
|
12
|
-
constructor(private revokedTokenRepository: Repository<RevokedToken>) {}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Revokes a JWT token by storing its JTI in the database
|
|
16
|
-
* @param token The token to revoke, containing at least the JTI and expiration date
|
|
17
|
-
* @param refreshTokenExpiration The expiration time for the refresh token. We use it to set the expiration date of
|
|
18
|
-
* the session token.
|
|
19
|
-
*/
|
|
20
|
-
public async revokeToken(token: TRevokedToken, refreshTokenExpiration: StringValue): Promise<void> {
|
|
21
|
-
const tokens: TRevokedToken[] = [token];
|
|
22
|
-
|
|
23
|
-
if (token.sid) {
|
|
24
|
-
tokens.push({
|
|
25
|
-
jti: token.sid,
|
|
26
|
-
sid: token.sid,
|
|
27
|
-
expiresAt: new Date(Date.now() + ms(refreshTokenExpiration)),
|
|
28
|
-
tokenType: TOKEN_TYPE.SESSION,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
await this.revokeTokens(tokens);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public async revokeRefreshToken(token: TRevokedToken): Promise<void> {
|
|
36
|
-
await this.revokeTokens([token]);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private revokeTokens(tokens: TRevokedToken[]): Promise<void> {
|
|
40
|
-
return this.revokedTokenRepository
|
|
41
|
-
.createQueryBuilder()
|
|
42
|
-
.insert()
|
|
43
|
-
.into(RevokedToken)
|
|
44
|
-
.values(tokens)
|
|
45
|
-
.orIgnore()
|
|
46
|
-
.execute()
|
|
47
|
-
.then(() => {
|
|
48
|
-
this.logger.debug(`Tokens with JTI ${tokens.map(t => t.jti).join(', ')} have been revoked`);
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Checks if a token has been revoked
|
|
54
|
-
* @param jti The JWT token identifier
|
|
55
|
-
* @param sid Optional session identifier, used for session tokens
|
|
56
|
-
* @returns true if the token is revoked, false otherwise
|
|
57
|
-
*/
|
|
58
|
-
public async isTokenRevoked(jti: string, sid?: string): Promise<boolean> {
|
|
59
|
-
const whereConditions: FindOptionsWhere<RevokedToken>[] = [{ jti }];
|
|
60
|
-
|
|
61
|
-
if (sid) {
|
|
62
|
-
whereConditions.push({ sid, tokenType: TOKEN_TYPE.SESSION });
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const tokensCount = await this.revokedTokenRepository.count({
|
|
66
|
-
where: whereConditions,
|
|
67
|
-
});
|
|
68
|
-
return tokensCount > 0;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@Cron(CronExpression.EVERY_HOUR)
|
|
72
|
-
private async cleanupExpiredTokens() {
|
|
73
|
-
const now = new Date();
|
|
74
|
-
this.logger.debug('Starting cleanup of expired revoked tokens');
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const result = await this.revokedTokenRepository
|
|
78
|
-
.createQueryBuilder()
|
|
79
|
-
.delete()
|
|
80
|
-
.where('expiresAt < :now', { now })
|
|
81
|
-
.execute();
|
|
82
|
-
|
|
83
|
-
this.logger.log(`Cleaned up ${result.affected || 0} expired revoked tokens`);
|
|
84
|
-
} catch (error) {
|
|
85
|
-
this.logger.error(`Error during revoked tokens cleanup: ${error.message}`, error.stack);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm';
|
|
2
|
-
|
|
3
|
-
@Entity('settings')
|
|
4
|
-
export class Setting {
|
|
5
|
-
@PrimaryGeneratedColumn('uuid')
|
|
6
|
-
id: string;
|
|
7
|
-
|
|
8
|
-
@Column({ unique: true })
|
|
9
|
-
key: string;
|
|
10
|
-
|
|
11
|
-
@Column()
|
|
12
|
-
value: string;
|
|
13
|
-
|
|
14
|
-
@CreateDateColumn({ name: 'created_at' })
|
|
15
|
-
createdAt: Date;
|
|
16
|
-
|
|
17
|
-
@UpdateDateColumn({ name: 'updated_at' })
|
|
18
|
-
updatedAt: Date;
|
|
19
|
-
}
|
package/src/settings/index.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Setting } from "../entities/setting.entity";
|
|
2
|
-
import { Action, AppAbility, IPolicyHandler } from "../../casl";
|
|
3
|
-
|
|
4
|
-
export class ManageSettingsPolicy implements IPolicyHandler {
|
|
5
|
-
handle(ability: AppAbility) {
|
|
6
|
-
return ability.can(Action.Manage, Setting);
|
|
7
|
-
}
|
|
8
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Body, Controller, Get, Patch } from "@nestjs/common";
|
|
2
|
-
import { SettingsService } from "./settings.service";
|
|
3
|
-
import { ManageSettingsPolicy } from "./policies/manage-settings.policy";
|
|
4
|
-
import { ApiOkResponse, ApiTags } from "@nestjs/swagger";
|
|
5
|
-
import { CheckPolicies, ManageAllPolicy } from "../casl";
|
|
6
|
-
import { EventSettingsDto } from "./dto/event-settings.dto";
|
|
7
|
-
|
|
8
|
-
@CheckPolicies(new ManageAllPolicy())
|
|
9
|
-
@ApiTags('Settings')
|
|
10
|
-
@Controller('settings')
|
|
11
|
-
export class SettingsController {
|
|
12
|
-
constructor(
|
|
13
|
-
private readonly settingsService: SettingsService,
|
|
14
|
-
) {}
|
|
15
|
-
|
|
16
|
-
@CheckPolicies(new ManageSettingsPolicy())
|
|
17
|
-
@Get('events')
|
|
18
|
-
@ApiOkResponse({
|
|
19
|
-
type: EventSettingsDto,
|
|
20
|
-
})
|
|
21
|
-
getEventSettings(): Promise<EventSettingsDto> {
|
|
22
|
-
return this.settingsService.getEventSettings();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@CheckPolicies(new ManageSettingsPolicy())
|
|
26
|
-
@Patch('events')
|
|
27
|
-
setEventSettings(
|
|
28
|
-
@Body() events: EventSettingsDto,
|
|
29
|
-
) {
|
|
30
|
-
return this.settingsService.setEventSettings(events);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { DynamicModule, Module } from '@nestjs/common';
|
|
2
|
-
import { getDataSourceToken, TypeOrmModule } from '@nestjs/typeorm';
|
|
3
|
-
import { SettingsController } from "./settings.controller";
|
|
4
|
-
import { SettingsService } from "./settings.service";
|
|
5
|
-
import { Setting } from "./entities/setting.entity";
|
|
6
|
-
import { DataSource } from "typeorm";
|
|
7
|
-
import { Action, CaslAbilityFactory } from "../casl";
|
|
8
|
-
import { SettingsPermissions } from "./settings.permissions";
|
|
9
|
-
|
|
10
|
-
@Module({})
|
|
11
|
-
export class SettingsModule {
|
|
12
|
-
static register(config: {
|
|
13
|
-
withControllers: boolean,
|
|
14
|
-
dataSourceName: string,
|
|
15
|
-
}): DynamicModule {
|
|
16
|
-
return {
|
|
17
|
-
module: SettingsModule,
|
|
18
|
-
imports: [
|
|
19
|
-
TypeOrmModule.forFeature([Setting], config.dataSourceName),
|
|
20
|
-
],
|
|
21
|
-
controllers: config.withControllers ? [
|
|
22
|
-
SettingsController,
|
|
23
|
-
] : [],
|
|
24
|
-
providers: [
|
|
25
|
-
{
|
|
26
|
-
provide: SettingsService,
|
|
27
|
-
inject: [getDataSourceToken(config.dataSourceName)],
|
|
28
|
-
useFactory: (dataSource: DataSource) => {
|
|
29
|
-
return new SettingsService(dataSource.getRepository(Setting));
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
],
|
|
33
|
-
exports: [
|
|
34
|
-
SettingsService,
|
|
35
|
-
],
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
constructor() {
|
|
40
|
-
CaslAbilityFactory.addPermissionToAction({
|
|
41
|
-
permission: SettingsPermissions.MANAGE,
|
|
42
|
-
action: Action.Manage,
|
|
43
|
-
subject: Setting,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { Injectable } from "@nestjs/common";
|
|
2
|
-
import { In, Like, Repository } from "typeorm";
|
|
3
|
-
import { Setting } from "./entities/setting.entity";
|
|
4
|
-
import { EventSettingsDto } from "./dto/event-settings.dto";
|
|
5
|
-
import { SettingsValues } from "./settings.constants";
|
|
6
|
-
|
|
7
|
-
@Injectable()
|
|
8
|
-
export class SettingsService {
|
|
9
|
-
constructor(readonly repo: Repository<Setting>) {
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
public getSettings(settingsNames: string[]): Promise<Setting[]> {
|
|
13
|
-
return this.repo.find({
|
|
14
|
-
where: {
|
|
15
|
-
key: In(settingsNames),
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async updateSettings(settings: Pick<Setting, 'key' | 'value'>[]): Promise<void> {
|
|
21
|
-
await this.repo.upsert(settings, ['key']);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async getEventSettings(): Promise<EventSettingsDto> {
|
|
25
|
-
const settings = await this.repo.find({
|
|
26
|
-
where: {
|
|
27
|
-
key: Like('notifications.%'),
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const eventSettings = new EventSettingsDto();
|
|
32
|
-
settings.forEach(setting => {
|
|
33
|
-
eventSettings[setting.key] = setting.value === SettingsValues.YES
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
return eventSettings;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async setEventSettings(updateDto: EventSettingsDto): Promise<void> {
|
|
40
|
-
const settings: Pick<Setting, 'key' | 'value'>[] = [];
|
|
41
|
-
|
|
42
|
-
for (const key in updateDto) {
|
|
43
|
-
settings.push({
|
|
44
|
-
key: key,
|
|
45
|
-
value: updateDto[key] ? SettingsValues.YES : SettingsValues.NO,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
await this.repo.upsert(settings, ['key']);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import Joi from "joi";
|
|
2
|
-
import { JoiSchema } from 'nestjs-joi';
|
|
3
|
-
|
|
4
|
-
export class TelegramSettingsUpdateDto {
|
|
5
|
-
@JoiSchema(Joi.boolean().optional())
|
|
6
|
-
enabled?: boolean;
|
|
7
|
-
|
|
8
|
-
@JoiSchema(Joi.string().trim().optional().allow(''))
|
|
9
|
-
botToken?: string;
|
|
10
|
-
|
|
11
|
-
@JoiSchema(Joi.string().trim().optional().allow(''))
|
|
12
|
-
chatId?: string;
|
|
13
|
-
}
|
package/src/telegraf/index.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { Body, Controller, Get, Patch, Post } from "@nestjs/common";
|
|
2
|
-
import { TelegrafService } from "./telegraf.service";
|
|
3
|
-
import { ApiOkResponse, ApiTags } from "@nestjs/swagger";
|
|
4
|
-
import { ManageSettingsPolicy } from "../settings/policies/manage-settings.policy";
|
|
5
|
-
import { CheckPolicies, ManageAllPolicy } from "../casl";
|
|
6
|
-
import { TelegramSettingsDto } from "./dto/telegram-settings.dto";
|
|
7
|
-
import { TelegramSettingsUpdateDto } from "./dto/telegram-settings-update.dto";
|
|
8
|
-
|
|
9
|
-
@CheckPolicies(new ManageAllPolicy())
|
|
10
|
-
@ApiTags('Telegraf')
|
|
11
|
-
@Controller('telegraf')
|
|
12
|
-
export class TelegrafController {
|
|
13
|
-
constructor(
|
|
14
|
-
private readonly telegrafService: TelegrafService,
|
|
15
|
-
) {
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@CheckPolicies(new ManageSettingsPolicy())
|
|
19
|
-
@Get('telegram')
|
|
20
|
-
@ApiOkResponse({
|
|
21
|
-
type: TelegramSettingsDto,
|
|
22
|
-
})
|
|
23
|
-
getTelegramSettings(): Promise<TelegramSettingsDto> {
|
|
24
|
-
return this.telegrafService.getTelegramSettings();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
@CheckPolicies(new ManageSettingsPolicy())
|
|
28
|
-
@Patch('telegram')
|
|
29
|
-
setTelegramSettings(
|
|
30
|
-
@Body() telegram: TelegramSettingsUpdateDto,
|
|
31
|
-
) {
|
|
32
|
-
return this.telegrafService.setTelegramSettings(telegram);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
@CheckPolicies(new ManageSettingsPolicy())
|
|
36
|
-
@Post('test')
|
|
37
|
-
async testTelegraf() {
|
|
38
|
-
return await this.telegrafService.test();
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { DynamicModule, Module } from "@nestjs/common";
|
|
2
|
-
import { TelegrafService } from "./telegraf.service";
|
|
3
|
-
import { SettingsModule } from "../settings/settings.module";
|
|
4
|
-
import { TelegrafController } from "./telegraf.controller";
|
|
5
|
-
|
|
6
|
-
@Module({})
|
|
7
|
-
export class TelegrafModule {
|
|
8
|
-
static register(config: {
|
|
9
|
-
withControllers: boolean,
|
|
10
|
-
dataSourceName: string,
|
|
11
|
-
}): DynamicModule {
|
|
12
|
-
return {
|
|
13
|
-
module: TelegrafModule,
|
|
14
|
-
imports: [
|
|
15
|
-
SettingsModule.register({ withControllers: false, dataSourceName: config.dataSourceName }),
|
|
16
|
-
],
|
|
17
|
-
controllers: config.withControllers ? [
|
|
18
|
-
TelegrafController,
|
|
19
|
-
] : [],
|
|
20
|
-
providers: [
|
|
21
|
-
TelegrafService,
|
|
22
|
-
],
|
|
23
|
-
exports: [
|
|
24
|
-
TelegrafService,
|
|
25
|
-
],
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
|
2
|
-
import { Notifications, Setting, SettingsService, SettingsValues } from "../settings";
|
|
3
|
-
import { FmtString } from "telegraf/format";
|
|
4
|
-
|
|
5
|
-
import { Telegraf } from "telegraf";
|
|
6
|
-
import { Telegram } from "./telegraf.constants";
|
|
7
|
-
import { TelegramSettingsDto } from "./dto/telegram-settings.dto";
|
|
8
|
-
import { TelegramSettingsUpdateDto } from "./dto/telegram-settings-update.dto";
|
|
9
|
-
|
|
10
|
-
export const settingsToDtoPropMap = {
|
|
11
|
-
[Telegram.Enabled]: 'enabled',
|
|
12
|
-
[Telegram.BotToken]: 'botToken',
|
|
13
|
-
[Telegram.ChatId]: 'chatId',
|
|
14
|
-
} as const;
|
|
15
|
-
|
|
16
|
-
@Injectable()
|
|
17
|
-
export class TelegrafService {
|
|
18
|
-
private readonly logger = new Logger(TelegrafService.name);
|
|
19
|
-
|
|
20
|
-
constructor(
|
|
21
|
-
private readonly settingsService: SettingsService,
|
|
22
|
-
) {
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async getTelegramSettings(): Promise<TelegramSettingsDto> {
|
|
26
|
-
const settings = await this.settingsService.getSettings([
|
|
27
|
-
Telegram.Enabled,
|
|
28
|
-
Telegram.BotToken,
|
|
29
|
-
Telegram.ChatId
|
|
30
|
-
])
|
|
31
|
-
|
|
32
|
-
const telegramSettings = {
|
|
33
|
-
enabled: false,
|
|
34
|
-
botToken: '',
|
|
35
|
-
chatId: '',
|
|
36
|
-
};
|
|
37
|
-
settings.forEach((setting) => {
|
|
38
|
-
switch (setting.key) {
|
|
39
|
-
case Telegram.Enabled:
|
|
40
|
-
telegramSettings[settingsToDtoPropMap[setting.key]] = setting.value === SettingsValues.YES;
|
|
41
|
-
break;
|
|
42
|
-
|
|
43
|
-
case Telegram.BotToken:
|
|
44
|
-
case Telegram.ChatId:
|
|
45
|
-
telegramSettings[settingsToDtoPropMap[setting.key]] = setting.value;
|
|
46
|
-
break;
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
return telegramSettings;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async setTelegramSettings(updateDto: TelegramSettingsUpdateDto): Promise<void> {
|
|
54
|
-
const settings: Pick<Setting, 'key' | 'value'>[] = [];
|
|
55
|
-
|
|
56
|
-
if (updateDto.enabled) {
|
|
57
|
-
settings.push({
|
|
58
|
-
key: Telegram.Enabled,
|
|
59
|
-
value: updateDto.enabled ? SettingsValues.YES : SettingsValues.NO,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (updateDto.botToken) {
|
|
64
|
-
settings.push({
|
|
65
|
-
key: Telegram.BotToken,
|
|
66
|
-
value: updateDto.botToken,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (updateDto.chatId) {
|
|
71
|
-
settings.push({
|
|
72
|
-
key: Telegram.ChatId,
|
|
73
|
-
value: updateDto.chatId,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
await this.settingsService.updateSettings(settings);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async sendMessage(message: string | FmtString, type: Notifications | null): Promise<void> {
|
|
81
|
-
const config = await this.getTelegramSettings();
|
|
82
|
-
if (!config.enabled) {
|
|
83
|
-
this.logger.log('Suppressed telegram message because it is disabled');
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (!config.botToken || !config.chatId) {
|
|
88
|
-
this.logger.log('Suppressed telegram message because bot token or chat id is not set');
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const bot = new Telegraf(config.botToken);
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
await bot.telegram.sendMessage(config.chatId, message);
|
|
96
|
-
} catch (e) {
|
|
97
|
-
this.logger.error('Failed to send telegram message');
|
|
98
|
-
this.logger.error(e, e.stack);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async test() {
|
|
103
|
-
try {
|
|
104
|
-
return await this.sendMessage('Test message', null);
|
|
105
|
-
} catch (e) {
|
|
106
|
-
this.logger.error(e, e.stack);
|
|
107
|
-
throw new BadRequestException('Wrong bot token or chat id')
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|