fix: prettier)

This commit is contained in:
2024-07-03 23:49:05 +03:00
parent a865789efa
commit 5e570a4f60
47 changed files with 5152 additions and 2835 deletions

View File

@@ -6,6 +6,9 @@ DATABASE_PORT=5432
SERVER_PORT=3000
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=123
REDIS_DB=1
JWT_SECRET=secret

View File

@@ -1,25 +1,22 @@
module.exports = {
parser: '@typescript-eslint/parser',
parser: "@typescript-eslint/parser",
parserOptions: {
project: 'tsconfig.json',
project: "tsconfig.json",
tsconfigRootDir: __dirname,
sourceType: 'module',
sourceType: "module",
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
plugins: ["@typescript-eslint/eslint-plugin"],
extends: ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
ignorePatterns: [".eslintrc.js"],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
},
};

Binary file not shown.

View File

@@ -1,6 +1,6 @@
import { CacheModuleAsyncOptions } from '@nestjs/cache-manager';
import { redisStore } from 'cache-manager-redis-store';
import { config } from 'config';
import { CacheModuleAsyncOptions } from "@nestjs/cache-manager";
import { redisStore } from "cache-manager-redis-store";
import { config } from "config";
export const RedisOptions: CacheModuleAsyncOptions = {
isGlobal: true,

View File

@@ -1,5 +1,5 @@
import { Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn } from 'typeorm';
import { User } from './user.entity';
import { Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn } from "typeorm";
import { User } from "./user.entity";
@Entity()
export class Admin {
@@ -13,7 +13,7 @@ export class Admin {
@Column({ nullable: false })
public user_id!: string;
@OneToOne(() => User, (user) => user.id, { onDelete: 'CASCADE', onUpdate: 'CASCADE' })
@JoinColumn({ name: 'user_id' })
@OneToOne(() => User, (user) => user.id, { onDelete: "CASCADE", onUpdate: "CASCADE" })
@JoinColumn({ name: "user_id" })
public user!: User;
}

View File

@@ -1,5 +1,5 @@
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
import { Post } from './post.entity';
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm";
import { Post } from "./post.entity";
@Entity()
export class Image {
@@ -19,7 +19,7 @@ export class Image {
@Column({ nullable: false })
public post_uuid!: string;
@ManyToOne(() => Post, (post) => post.uuid, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'post_uuid' })
@ManyToOne(() => Post, (post) => post.uuid, { onDelete: "CASCADE" })
@JoinColumn({ name: "post_uuid" })
public post!: Post;
}

View File

@@ -1,5 +1,5 @@
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { ProxyUser } from './proxy_user.entity';
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
import { ProxyUser } from "./proxy_user.entity";
@Entity()
export class Payment {
@@ -7,16 +7,16 @@ export class Payment {
Object.assign(this, props);
}
@PrimaryGeneratedColumn('increment')
@PrimaryGeneratedColumn("increment")
public id!: number;
@Column()
public user_uuid!: string;
@Column({ type: 'timestamptz' })
@Column({ type: "timestamptz" })
public payTime!: Date;
@ManyToOne(() => ProxyUser, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'user_uuid' })
@ManyToOne(() => ProxyUser, { onDelete: "CASCADE" })
@JoinColumn({ name: "user_uuid" })
user: ProxyUser;
}

View File

@@ -1,13 +1,13 @@
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { Admin } from './admin.entity';
import { Image } from './image.entity';
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { Admin } from "./admin.entity";
import { Image } from "./image.entity";
@Entity()
export class Post {
constructor(props?: Partial<Post>) {
Object.assign(this, props);
}
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
public uuid!: string;
@Column({ default: false })
@@ -19,17 +19,17 @@ export class Post {
@Column({ nullable: true })
public media_group_id: string;
@Column({ type: 'timestamptz' })
@Column({ type: "timestamptz" })
public timestamp!: Date;
@Column({ type: 'timestamptz', nullable: true })
@Column({ type: "timestamptz", nullable: true })
public edit_timestamp?: Date;
@Column({ nullable: false })
public from_user_id!: string;
@ManyToOne(() => Admin, (admin) => admin.user.id)
@JoinColumn({ name: 'from_user_id', referencedColumnName: 'user_id' })
@JoinColumn({ name: "from_user_id", referencedColumnName: "user_id" })
public from_user!: Admin;
@OneToMany(() => Image, (image) => image.post)

View File

@@ -1,6 +1,6 @@
import { Column, Entity, JoinColumn, OneToMany, OneToOne, PrimaryGeneratedColumn } from 'typeorm';
import { Payment } from './payment.entity';
import { User } from './user.entity';
import { Column, Entity, JoinColumn, OneToMany, OneToOne, PrimaryGeneratedColumn } from "typeorm";
import { Payment } from "./payment.entity";
import { User } from "./user.entity";
@Entity()
export class ProxyUser {
@@ -8,7 +8,7 @@ export class ProxyUser {
Object.assign(this, props);
}
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
public uuid!: string;
@Column({ nullable: false, unique: true })
@@ -20,14 +20,18 @@ export class ProxyUser {
@Column({ nullable: false })
public link!: string;
@Column({ nullable: false, type: 'timestamptz' })
@Column({ nullable: false, type: "timestamptz" })
public connectDate!: Date;
@Column({ nullable: true })
public user_id!: string;
@OneToOne(() => User, (user) => user.id, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: true })
@JoinColumn({ name: 'user_id' })
@OneToOne(() => User, (user) => user.id, {
onDelete: "CASCADE",
onUpdate: "CASCADE",
nullable: true,
})
@JoinColumn({ name: "user_id" })
public user?: User;
@OneToMany(() => Payment, (payment) => payment.user)

View File

@@ -1,4 +1,4 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class BotSettings {
@@ -6,10 +6,10 @@ export class BotSettings {
Object.assign(this, props);
}
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
public uuid!: string;
@Column({ type: 'text', array: true })
@Column({ type: "text", array: true })
public messageTimes!: string[];
@Column()

View File

@@ -1,4 +1,4 @@
import { Column, Entity, PrimaryColumn } from 'typeorm';
import { Column, Entity, PrimaryColumn } from "typeorm";
@Entity()
export class User {

View File

@@ -1,5 +1,5 @@
export enum EGetAll {
all = 'all',
will_post = 'will-post',
posted = 'posted',
all = "all",
will_post = "will-post",
posted = "posted",
}

View File

@@ -23,11 +23,12 @@
"@nestjs/cache-manager": "2.2.1",
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/swagger": "^7.1.16",
"@nestjs/typeorm": "^10.0.1",
"bcrypt": "^5.1.1",
"bcryptjs": "^2.4.3",
"cache-manager": "^5.4.0",
"cache-manager-redis-store": "^3.0.1",
"dotenv": "^16.3.1",
@@ -42,6 +43,8 @@
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/bcryptjs": "^2.4.6",
"@types/bun": "latest",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
@@ -60,8 +63,7 @@
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3",
"@types/bun": "latest"
"typescript": "^5.1.3"
},
"jest": {
"moduleFileExtensions": [

5598
backend/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { Controller, Get } from "@nestjs/common";
import { ApiOperation, ApiTags } from "@nestjs/swagger";
@ApiTags('App')
@ApiTags("App")
@Controller()
export class AppController {
@ApiOperation({ description: 'check site availability' })
@Get('ping')
@ApiOperation({ description: "check site availability" })
@Get("ping")
pingpong() {
return 'pong';
return "pong";
}
}

View File

@@ -1,18 +1,18 @@
import { CacheModule } from '@nestjs/cache-manager';
import { Module } from '@nestjs/common';
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
import { config } from 'config';
import { RedisOptions } from 'config/redis-options';
import { LibsModule } from 'libs/libs.module';
import { AppController } from './app.controller';
import { AdminModule } from './modules/admin/admin.module';
import { AuthModule } from './modules/auth/auth.module';
import { ImageModule } from './modules/image/image.module';
import { AppInitService } from './modules/initialization/app.init.service';
import { PostModule } from './modules/post/post.module';
import { ProxyModule } from './modules/proxy/proxy.module';
import { SettingsModule } from './modules/settings/settings.module';
import { UserModule } from './modules/user/user.module';
import { CacheModule } from "@nestjs/cache-manager";
import { Module } from "@nestjs/common";
import { TypeOrmModule, TypeOrmModuleOptions } from "@nestjs/typeorm";
import { config } from "config";
import { RedisOptions } from "config/redis-options";
import { LibsModule } from "libs/libs.module";
import { AppController } from "./app.controller";
import { AdminModule } from "./modules/admin/admin.module";
import { AuthModule } from "./modules/auth/auth.module";
import { ImageModule } from "./modules/image/image.module";
import { AppInitService } from "./modules/initialization/app.init.service";
import { PostModule } from "./modules/post/post.module";
import { ProxyModule } from "./modules/proxy/proxy.module";
import { SettingsModule } from "./modules/settings/settings.module";
import { UserModule } from "./modules/user/user.module";
@Module({
imports: [
@@ -28,9 +28,6 @@ import { UserModule } from './modules/user/user.module';
TypeOrmModule.forRoot(<TypeOrmModuleOptions>config.database),
],
controllers: [AppController],
providers: [
AppInitService,
// { provide: APP_GUARD, useClass: AuthGuard }, // Если будет необходима авторизация
],
providers: [AppInitService],
})
export class AppModule {}

View File

@@ -1,14 +1,16 @@
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { config } from 'config';
import { AppModule } from './app.module';
import { swagger } from './swagger';
import { Logger } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
import { config } from "config";
import { AppModule } from "./app.module";
import { swagger } from "./swagger";
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: ['log', 'debug', 'error', 'warn', 'verbose'],
logger: ["log", "debug", "error", "warn", "verbose"],
});
swagger(app);
await app.listen(config.server.port, () => Logger.log(`Server started on port ${config.server.port}`));
await app.listen(config.server.port, () =>
Logger.log(`Server started on port ${config.server.port}`),
);
}
bootstrap();

View File

@@ -1,26 +1,26 @@
import { CacheInterceptor, CacheKey, CacheTTL } from '@nestjs/cache-manager';
import { Controller, Get, Param, UseInterceptors } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { AdminService } from './admin.service';
import { CacheInterceptor, CacheKey, CacheTTL } from "@nestjs/cache-manager";
import { Controller, Get, Param, UseInterceptors } from "@nestjs/common";
import { ApiOperation, ApiTags } from "@nestjs/swagger";
import { AdminService } from "./admin.service";
@ApiTags('Admin')
@Controller('admin')
@ApiTags("Admin")
@Controller("admin")
export class AdminController {
constructor(private adminService: AdminService) {}
@ApiOperation({
description: 'Get admins from db',
description: "Get admins from db",
})
@CacheKey('admins')
@CacheKey("admins")
@CacheTTL({ ttl: 5 } as any)
@UseInterceptors(CacheInterceptor)
@Get('get')
@Get("get")
async getAdmin() {
return await this.adminService.getAdmins();
}
@ApiOperation({ description: 'Check admin is or not' })
@Get('is-admin/:id')
async isAdmin(@Param('id') id: string) {
@ApiOperation({ description: "Check admin is or not" })
@Get("is-admin/:id")
async isAdmin(@Param("id") id: string) {
return await this.adminService.checkIsAdmin(id);
}
}

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { LibsModule } from 'libs/libs.module';
import { AdminController } from './admin.controller';
import { AdminService } from './admin.service';
import { Module } from "@nestjs/common";
import { LibsModule } from "libs/libs.module";
import { AdminController } from "./admin.controller";
import { AdminService } from "./admin.service";
@Module({
imports: [LibsModule],

View File

@@ -1,9 +1,9 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Inject, Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Cache } from 'cache-manager';
import { Admin } from 'libs/database/admin.entity';
import { Repository } from 'typeorm';
import { CACHE_MANAGER } from "@nestjs/cache-manager";
import { Inject, Injectable, Logger } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Cache } from "cache-manager";
import { Admin } from "libs/database/admin.entity";
import { Repository } from "typeorm";
@Injectable()
export class AdminService {
private readonly logger: Logger = new Logger(AdminService.name);
@@ -15,7 +15,10 @@ export class AdminService {
async getAdmins() {
try {
this.logger.debug(`[admin.getAdmins]`);
const admins = await this.adminRepository.find({ relations: { user: true }, select: { user_id: true, user: { user_name: true } } });
const admins = await this.adminRepository.find({
relations: { user: true },
select: { user_id: true, user: { user_name: true } },
});
const result: { user_id: string; user_name: string }[] = admins.map((admin) => ({
user_id: admin.user_id,
user_name: admin.user.user_name,

View File

@@ -30,7 +30,6 @@ export class AuthController {
@ApiOperation({
description: "Register into system",
})
@HttpCode(HttpStatus.CREATED)
@Post("register")
register(@Body() signInDto: LoginDto) {
return this.authService.register(signInDto.username, signInDto.password);

View File

@@ -2,30 +2,3 @@ import { Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
@Injectable()
export class JwtGuard extends AuthGuard("jwt") {}
// export class AuthGuard implements CanActivate {
// constructor(private jwtService: JwtService) {}
// async canActivate(context: ExecutionContext): Promise<boolean> {
// const request = context.switchToHttp().getRequest();
// const token = this.extractTokenFromHeader(request);
// if (!token) {
// throw new UnauthorizedException();
// }
// try {
// const payload = await this.jwtService.verifyAsync(token, {
// secret: config.auth.jwt_secret,
// });
// request["user"] = payload;
// } catch {
// throw new UnauthorizedException();
// }
// return true;
// }
// private extractTokenFromHeader(request: Request): string | undefined {
// const [type, token] = request.headers.authorization.split(" ") ?? [];
// return type === "Bearer" ? token : undefined;
// }
// }

View File

@@ -1,7 +1,7 @@
import { Injectable, Logger, UnauthorizedException } from "@nestjs/common";
import { ImATeapotException, Injectable, Logger, UnauthorizedException } from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { InjectRepository } from "@nestjs/typeorm";
import * as bcrypt from "bcrypt";
import * as bcrypt from "bcryptjs";
import { WebUser } from "libs/database/web_user.entity";
import { Repository } from "typeorm";
@@ -35,6 +35,7 @@ export class AuthService {
}
async register(username: string, password: string): Promise<{ access_token: string }> {
if (1) throw new ImATeapotException();
const user = await this.userRepository.findOne({ where: { login: username } });
if (user) throw new UnauthorizedException("User already exists");
const salt = await bcrypt.genSalt();

View File

@@ -1,15 +1,15 @@
import { Body, Controller, Post } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { IAddImage } from './image.dto';
import { ImageService } from './image.service';
import { Body, Controller, Post } from "@nestjs/common";
import { ApiOperation, ApiTags } from "@nestjs/swagger";
import { IAddImage } from "./image.dto";
import { ImageService } from "./image.service";
@ApiTags('Image')
@Controller('image')
@ApiTags("Image")
@Controller("image")
export class ImageController {
constructor(private imageService: ImageService) {}
@ApiOperation({ description: 'A method to add photo to post' })
@Post('add')
@ApiOperation({ description: "A method to add photo to post" })
@Post("add")
async addImage(@Body() data: IAddImage) {
return await this.imageService.add(data);
}

View File

@@ -1,12 +1,23 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
export class IAddImage {
// @ApiProperty({ description: 'A post that contains this photo', example: '1212-4324-asdf-23432' }) readonly post_id!: string;
@ApiProperty({ description: 'A telegram file id of photo', example: '1214244' }) readonly file_id!: string;
@ApiProperty({ description: 'Has image the spoiler?', example: false }) readonly has_spoiler!: boolean;
@ApiProperty({ description: 'A photo message id', example: '123124' }) readonly message_id!: number;
@ApiProperty({ description: 'Post text', example: '#neurowaifu', required: false }) readonly post_text?: string;
@ApiProperty({ description: 'A media group id of the photo', example: '1241244', required: false }) readonly media_group_id?: string;
@ApiProperty({ description: 'Message entities of text', example: '[]' }) readonly message_entities?: string;
@ApiProperty({ description: 'The id of user that creating post', example: '1234' }) readonly from_user_id!: string;
@ApiProperty({ description: "A telegram file id of photo", example: "1214244" })
readonly file_id!: string;
@ApiProperty({ description: "Has image the spoiler?", example: false })
readonly has_spoiler!: boolean;
@ApiProperty({ description: "A photo message id", example: "123124" })
readonly message_id!: number;
@ApiProperty({ description: "Post text", example: "#neurowaifu", required: false })
readonly post_text?: string;
@ApiProperty({
description: "A media group id of the photo",
example: "1241244",
required: false,
})
readonly media_group_id?: string;
@ApiProperty({ description: "Message entities of text", example: "[]" })
readonly message_entities?: string;
@ApiProperty({ description: "The id of user that creating post", example: "1234" })
readonly from_user_id!: string;
}

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { LibsModule } from 'libs/libs.module';
import { ImageController } from './image.controller';
import { ImageService } from './image.service';
import { Module } from "@nestjs/common";
import { LibsModule } from "libs/libs.module";
import { ImageController } from "./image.controller";
import { ImageService } from "./image.service";
@Module({
imports: [LibsModule],

View File

@@ -1,9 +1,9 @@
import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common';
import { Admin } from 'libs/database/admin.entity';
import { Image } from 'libs/database/image.entity';
import { Post } from 'libs/database/post.entity';
import { DataSource, EntityManager } from 'typeorm';
import { IAddImage } from './image.dto';
import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common";
import { Admin } from "libs/database/admin.entity";
import { Image } from "libs/database/image.entity";
import { Post } from "libs/database/post.entity";
import { DataSource, EntityManager } from "typeorm";
import { IAddImage } from "./image.dto";
@Injectable()
export class ImageService {
private readonly logger: Logger = new Logger(ImageService.name);
@@ -15,7 +15,9 @@ export class ImageService {
await this.dataSource.transaction(async (manager: EntityManager) => {
this.logger.log(`[image.add] data: ${JSON.stringify(data)}`);
if (data.media_group_id) {
let post = await manager.findOne(Post, { where: { media_group_id: data.media_group_id } });
let post = await manager.findOne(Post, {
where: { media_group_id: data.media_group_id },
});
if (post) {
await manager.save(Image, {
post: post,
@@ -29,7 +31,10 @@ export class ImageService {
post = await manager.save(Post, post);
}
} else {
const user = await manager.findOne(Admin, { where: { user: { id: data.from_user_id } }, relations: { user: true } });
const user = await manager.findOne(Admin, {
where: { user: { id: data.from_user_id } },
relations: { user: true },
});
post = await manager.save(Post, {
media_group_id: data.media_group_id,
text: data.post_text,
@@ -46,7 +51,10 @@ export class ImageService {
});
}
} else {
const user = await manager.findOne(Admin, { where: { user: { id: data.from_user_id } }, relations: { user: true } });
const user = await manager.findOne(Admin, {
where: { user: { id: data.from_user_id } },
relations: { user: true },
});
const post = await manager.save(Post, {
text: data.post_text,
message_entities: data.message_entities,
@@ -61,10 +69,10 @@ export class ImageService {
});
}
});
return { status: 'ok', created: created_new };
return { status: "ok", created: created_new };
} catch (error) {
this.logger.debug(`[image.add] error: ${JSON.stringify(error)}`);
throw new HttpException('No posts', HttpStatus.BAD_REQUEST);
throw new HttpException("No posts", HttpStatus.BAD_REQUEST);
}
}
}

View File

@@ -1,11 +1,12 @@
import { Injectable, OnModuleInit } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Admin } from 'libs/database/admin.entity';
import { Image } from 'libs/database/image.entity';
import { Post } from 'libs/database/post.entity';
import { BotSettings } from 'libs/database/settings.entity';
import { User } from 'libs/database/user.entity';
import { Repository } from 'typeorm';
import { Injectable, OnModuleInit } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Admin } from "libs/database/admin.entity";
import { Image } from "libs/database/image.entity";
import { Post } from "libs/database/post.entity";
import { BotSettings } from "libs/database/settings.entity";
import { User } from "libs/database/user.entity";
import { WebUser } from "libs/database/web_user.entity";
import { Repository } from "typeorm";
@Injectable()
export class AppInitService implements OnModuleInit {
@@ -15,6 +16,7 @@ export class AppInitService implements OnModuleInit {
@InjectRepository(Post) private postRepository: Repository<Post>,
@InjectRepository(Image) private ImageRepository: Repository<Image>,
@InjectRepository(BotSettings) private BotSettingsRepository: Repository<BotSettings>,
@InjectRepository(WebUser) private WebUserRepository: Repository<WebUser>,
) {}
async onModuleInit() {}

View File

@@ -1,78 +1,78 @@
import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger';
import { EGetAll } from 'libs/enums/getAll.enum';
import { ICreatePost, IEditPost } from './post.dto';
import { PostService } from './post.service';
import { Body, Controller, Delete, Get, Param, Post, Put } from "@nestjs/common";
import { ApiOperation, ApiParam, ApiTags } from "@nestjs/swagger";
import { EGetAll } from "libs/enums/getAll.enum";
import { ICreatePost, IEditPost } from "./post.dto";
import { PostService } from "./post.service";
@ApiTags('Post')
@Controller('post')
@ApiTags("Post")
@Controller("post")
export class PostController {
constructor(private postService: PostService) {}
@ApiOperation({ description: 'Creates a new post' })
@Post('new')
@ApiOperation({ description: "Creates a new post" })
@Post("new")
async newPost(@Body() data: ICreatePost) {
return await this.postService.newPost(data);
}
@ApiOperation({ description: 'Getting all posts. By default - all' })
@Get('get-all/:status')
@ApiParam({ name: 'status', required: false, enum: EGetAll })
async getAllPosts(@Param('status') status?: EGetAll) {
@ApiOperation({ description: "Getting all posts. By default - all" })
@Get("get-all/:status")
@ApiParam({ name: "status", required: false, enum: EGetAll })
async getAllPosts(@Param("status") status?: EGetAll) {
return await this.postService.getAllPosts(status || EGetAll.all);
}
@ApiOperation({ description: 'Getting a post by uuid' })
@Get('get/:postId')
async getPost(@Param('postId') postId: string) {
@ApiOperation({ description: "Getting a post by uuid" })
@Get("get/:postId")
async getPost(@Param("postId") postId: string) {
return await this.postService.getPost(postId);
}
@ApiOperation({ description: 'Getting a post by its media group id' })
@Get('get-by-media-group-id/:mediaGroupId')
async getByMediaGroup(@Param('mediaGroupId') mediaGroupId: string) {
@ApiOperation({ description: "Getting a post by its media group id" })
@Get("get-by-media-group-id/:mediaGroupId")
async getByMediaGroup(@Param("mediaGroupId") mediaGroupId: string) {
return await this.postService.getByMediaGroup(mediaGroupId);
}
@ApiOperation({ description: 'Editing a post by its uuid' })
@Post('edit/:postId')
async editPost(@Param('postId') postId: string, @Body() data: IEditPost) {
@ApiOperation({ description: "Editing a post by its uuid" })
@Post("edit/:postId")
async editPost(@Param("postId") postId: string, @Body() data: IEditPost) {
return await this.postService.editPost(postId, data);
}
@ApiOperation({ description: 'Editing post text by its order num' })
@Post('edit-post-by-order-num/:order')
async editPostByOrderNum(@Param('order') order: string, @Body() data: IEditPost) {
@ApiOperation({ description: "Editing post text by its order num" })
@Post("edit-post-by-order-num/:order")
async editPostByOrderNum(@Param("order") order: string, @Body() data: IEditPost) {
return await this.postService.editPostByOrderNum(order, data);
}
@ApiOperation({ description: 'Get post to post' })
@Get('post')
@ApiOperation({ description: "Get post to post" })
@Get("post")
async post() {
return await this.postService.post();
}
@ApiOperation({ description: 'Get post by order' })
@Get('get-post-by-order/:order')
async getPostByOrder(@Param('order') order: number) {
@ApiOperation({ description: "Get post by order" })
@Get("get-post-by-order/:order")
async getPostByOrder(@Param("order") order: number) {
return await this.postService.getPostByOrder(order);
}
@ApiOperation({ description: 'Delete post by order' })
@Delete('delete-post-by-order/:order')
async deletePostByOrder(@Param('order') order: number) {
@ApiOperation({ description: "Delete post by order" })
@Delete("delete-post-by-order/:order")
async deletePostByOrder(@Param("order") order: number) {
return await this.postService.deletePostByOrder(order);
}
@ApiOperation({ description: 'Get deleted posts' })
@Get('get-deleted')
@ApiOperation({ description: "Get deleted posts" })
@Get("get-deleted")
async getDeletedPosts() {
return await this.postService.getDeletedPosts();
}
@ApiOperation({ description: 'Restore post by order' })
@Put('restore-post-by-order/:order')
async restorePostByOrder(@Param('order') order: string) {
@ApiOperation({ description: "Restore post by order" })
@Put("restore-post-by-order/:order")
async restorePostByOrder(@Param("order") order: string) {
return await this.postService.restorePostByOrder(order);
}
}

View File

@@ -1,17 +1,21 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
export class ICreatePost {
@ApiProperty({ description: 'Post text', example: 'Post text' }) readonly text!: string;
@ApiProperty({ description: "Post text", example: "Post text" }) readonly text!: string;
@ApiProperty({ description: 'The id of user that creating post', example: '1234' }) readonly from_user_id!: string;
@ApiProperty({ description: "The id of user that creating post", example: "1234" })
readonly from_user_id!: string;
@ApiProperty({ description: 'Post media group id', example: '123' }) readonly media_group_id?: string;
@ApiProperty({ description: "Post media group id", example: "123" })
readonly media_group_id?: string;
@ApiProperty({ description: 'Message entities of text', example: '[]' }) readonly message_entities?: string;
@ApiProperty({ description: "Message entities of text", example: "[]" })
readonly message_entities?: string;
}
export class IEditPost {
@ApiProperty({ description: 'Post text', example: 'Post text' }) readonly text!: string;
@ApiProperty({ description: "Post text", example: "Post text" }) readonly text!: string;
@ApiProperty({ description: 'Message entities of text', example: '[]' }) readonly message_entities?: string;
@ApiProperty({ description: "Message entities of text", example: "[]" })
readonly message_entities?: string;
}

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { LibsModule } from 'libs/libs.module';
import { PostController } from './post.controller';
import { PostService } from './post.service';
import { Module } from "@nestjs/common";
import { LibsModule } from "libs/libs.module";
import { PostController } from "./post.controller";
import { PostService } from "./post.service";
@Module({
imports: [LibsModule],

View File

@@ -1,10 +1,10 @@
import { HttpException, HttpStatus, Inject, Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Admin } from 'libs/database/admin.entity';
import { Post } from 'libs/database/post.entity';
import { EGetAll } from 'libs/enums/getAll.enum';
import { DataSource, EntityManager, Repository } from 'typeorm';
import { ICreatePost, IEditPost } from './post.dto';
import { HttpException, HttpStatus, Inject, Injectable, Logger } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Admin } from "libs/database/admin.entity";
import { Post } from "libs/database/post.entity";
import { EGetAll } from "libs/enums/getAll.enum";
import { DataSource, EntityManager, Repository } from "typeorm";
import { ICreatePost, IEditPost } from "./post.dto";
@Injectable()
export class PostService {
@@ -19,7 +19,10 @@ export class PostService {
try {
this.logger.log(`[post.newPost] data: ${JSON.stringify(data)}`);
let result: Post = null;
const user = await this.adminRepository.findOne({ where: { user: { id: data.from_user_id } }, relations: { user: true } });
const user = await this.adminRepository.findOne({
where: { user: { id: data.from_user_id } },
relations: { user: true },
});
await this.dataSource.transaction(async (manager: EntityManager) => {
result = await manager.save(Post, {
text: data.text,
@@ -33,7 +36,7 @@ export class PostService {
return result;
} catch (error) {
this.logger.debug(`[post.newPost] error: ${error}`);
throw new HttpException('No user with this id', HttpStatus.BAD_REQUEST);
throw new HttpException("No user with this id", HttpStatus.BAD_REQUEST);
}
}
@@ -42,7 +45,7 @@ export class PostService {
this.logger.log(`[post.editPost] data: ${JSON.stringify(data)}`);
const post = await this.postRepository.findOne({ where: { uuid: postId } });
if (!post) {
throw new HttpException('Post not found', HttpStatus.NOT_FOUND);
throw new HttpException("Post not found", HttpStatus.NOT_FOUND);
}
if (post.text !== data.text) {
post.text = data.text;
@@ -52,16 +55,22 @@ export class PostService {
return post;
} catch (error) {
this.logger.debug(`[post.editPost] error: ${JSON.stringify(error)}`);
throw new HttpException('Post not found', HttpStatus.NOT_FOUND);
throw new HttpException("Post not found", HttpStatus.NOT_FOUND);
}
}
async editPostByOrderNum(order: string, data: IEditPost) {
try {
this.logger.log(`[post.editPostByOrderNum] data: ${JSON.stringify(data)}`);
const posts = await this.postRepository.find({ where: { posted: false, deleted: false }, order: { timestamp: 'ASC' } });
const posts = await this.postRepository.find({
where: { posted: false, deleted: false },
order: { timestamp: "ASC" },
});
if (Math.abs(+order) > posts.length) {
throw new HttpException('There are only ' + posts.length + ' unsent messages.', HttpStatus.BAD_REQUEST);
throw new HttpException(
"There are only " + posts.length + " unsent messages.",
HttpStatus.BAD_REQUEST,
);
}
const post = posts[Math.abs(+order) - 1];
if (post.text !== data.text || post.message_entities !== data.message_entities) {
@@ -76,8 +85,10 @@ export class PostService {
this.logger.debug(`[post.editPostByOrderNum] Order: ${order} is bad`);
throw error;
}
this.logger.debug(`[post.editPostByOrderNum] Bad data. Order: ${order}. Data: ${JSON.stringify(data)}`);
throw new HttpException('Server error', HttpStatus.BAD_GATEWAY);
this.logger.debug(
`[post.editPostByOrderNum] Bad data. Order: ${order}. Data: ${JSON.stringify(data)}`,
);
throw new HttpException("Server error", HttpStatus.BAD_GATEWAY);
}
}
@@ -86,13 +97,13 @@ export class PostService {
let obj: object;
switch (status) {
case EGetAll.will_post:
obj = { where: { posted: false, deleted: false }, order: { timestamp: 'ASC' } };
obj = { where: { posted: false, deleted: false }, order: { timestamp: "ASC" } };
break;
case EGetAll.all:
obj = { order: { timestamp: 'ASC' }, where: { deleted: false } };
obj = { order: { timestamp: "ASC" }, where: { deleted: false } };
break;
case EGetAll.posted:
obj = { where: { posted: true, deleted: false }, order: { timestamp: 'ASC' } };
obj = { where: { posted: true, deleted: false }, order: { timestamp: "ASC" } };
break;
}
return await this.postRepository.find(obj);
@@ -105,12 +116,15 @@ export class PostService {
async getPost(postId: string) {
try {
this.logger.log(`[post.getPost] data: ${postId}`);
const post = await this.postRepository.findOne({ where: { uuid: postId }, relations: { images: true } });
const post = await this.postRepository.findOne({
where: { uuid: postId },
relations: { images: true },
});
if (!post) throw new Error("Can't find post");
return post;
} catch (error) {
this.logger.log(`[post.getPost] error: ${JSON.stringify(error)}`);
throw new HttpException('No post with this id', HttpStatus.NOT_FOUND);
throw new HttpException("No post with this id", HttpStatus.NOT_FOUND);
}
}
@@ -119,16 +133,19 @@ export class PostService {
this.logger.log(`[post.getPostByOrder] data: ${order}`);
const posts = await this.postRepository.find({
relations: { images: true },
order: { timestamp: 'ASC' },
order: { timestamp: "ASC" },
where: { posted: false, deleted: false },
});
if (Math.abs(+order) > posts.length) {
throw new HttpException('There are only ' + posts.length + ' posts.', HttpStatus.BAD_REQUEST);
throw new HttpException(
"There are only " + posts.length + " posts.",
HttpStatus.BAD_REQUEST,
);
}
return posts[Math.abs(+order) - 1];
} catch (error) {
this.logger.log(`[post.getPostByOrder] error: ${JSON.stringify(error)}`);
throw new HttpException('No post with this id', HttpStatus.NOT_FOUND);
throw new HttpException("No post with this id", HttpStatus.NOT_FOUND);
}
}
@@ -150,11 +167,11 @@ export class PostService {
async post() {
try {
const posts = await this.postRepository.find({
order: { timestamp: 'ASC' },
order: { timestamp: "ASC" },
where: { posted: false, deleted: false },
relations: { images: true },
});
if (!posts.length) throw new HttpException('Nothing to post', HttpStatus.NOT_FOUND);
if (!posts.length) throw new HttpException("Nothing to post", HttpStatus.NOT_FOUND);
const post = posts[0];
post.posted = true;
this.logger.log(`[post.post] Post ${post.uuid} is posted`);
@@ -162,19 +179,25 @@ export class PostService {
return post;
} catch (error) {
if (error instanceof HttpException) {
this.logger.debug('[post.post] Not found');
this.logger.debug("[post.post] Not found");
throw error;
}
this.logger.debug(`[post.post] error: ${JSON.stringify(error)}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
async deletePostByOrder(order: number) {
try {
const posts = await this.postRepository.find({ order: { timestamp: 'ASC' }, where: { posted: false, deleted: false } });
const posts = await this.postRepository.find({
order: { timestamp: "ASC" },
where: { posted: false, deleted: false },
});
if (Math.abs(+order) > posts.length) {
throw new HttpException('There are only ' + posts.length + ' posts.', HttpStatus.BAD_REQUEST);
throw new HttpException(
"There are only " + posts.length + " posts.",
HttpStatus.BAD_REQUEST,
);
}
const post = posts[Math.abs(+order) - 1];
post.deleted = true;
@@ -183,28 +206,37 @@ export class PostService {
return post;
} catch (error) {
if (error instanceof HttpException) {
this.logger.debug('[post.deletePostByOrder] Not found');
this.logger.debug("[post.deletePostByOrder] Not found");
throw error;
}
this.logger.debug(`[post.deletePostByOrder] error: ${JSON.stringify(error)}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
async getDeletedPosts() {
try {
return await this.postRepository.find({ where: { deleted: true, posted: false }, order: { timestamp: 'ASC' } });
return await this.postRepository.find({
where: { deleted: true, posted: false },
order: { timestamp: "ASC" },
});
} catch (error) {
this.logger.debug(`[post.getDeleted] error: ${JSON.stringify(error)}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
async restorePostByOrder(order: string) {
try {
const posts = await this.postRepository.find({ order: { timestamp: 'ASC' }, where: { deleted: true, posted: false } });
const posts = await this.postRepository.find({
order: { timestamp: "ASC" },
where: { deleted: true, posted: false },
});
if (Math.abs(+order) > posts.length) {
throw new HttpException('There are only ' + posts.length + ' posts.', HttpStatus.BAD_REQUEST);
throw new HttpException(
"There are only " + posts.length + " posts.",
HttpStatus.BAD_REQUEST,
);
}
const post = posts[Math.abs(+order) - 1];
post.deleted = false;
@@ -213,11 +245,11 @@ export class PostService {
return post;
} catch (error) {
if (error instanceof HttpException) {
this.logger.debug('[post.restorePost] Not found');
this.logger.debug("[post.restorePost] Not found");
throw error;
}
this.logger.debug(`[post.restorePost] error: ${JSON.stringify(error)}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
}

View File

@@ -1,45 +1,45 @@
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { IOperation, IProxyUser } from './proxy.dto';
import { ProxyService } from './proxy.service';
import { Body, Controller, Get, Param, Post } from "@nestjs/common";
import { ApiOperation, ApiTags } from "@nestjs/swagger";
import { IOperation, IProxyUser } from "./proxy.dto";
import { ProxyService } from "./proxy.service";
@ApiTags('Proxy')
@Controller('proxy')
@ApiTags("Proxy")
@Controller("proxy")
export class ProxyController {
constructor(private proxyService: ProxyService) {}
@ApiOperation({ description: 'Method to create a new proxy user' })
@Post('new-user')
@ApiOperation({ description: "Method to create a new proxy user" })
@Post("new-user")
async newUser(@Body() data: IProxyUser) {
return await this.proxyService.newUser(data);
}
@ApiOperation({ description: 'get user by its username' })
@Get('get-user/:userName')
async getUser(@Param('userName') userName: string) {
@ApiOperation({ description: "get user by its username" })
@Get("get-user/:userName")
async getUser(@Param("userName") userName: string) {
return await this.proxyService.getUser(userName);
}
@ApiOperation({ description: 'get all users of proxy' })
@Get('get-all-users')
@ApiOperation({ description: "get all users of proxy" })
@Get("get-all-users")
async getAllUsers() {
return await this.proxyService.getAllUsers();
}
@ApiOperation({ description: 'adding an operation to user' })
@Post('operation/add')
@ApiOperation({ description: "adding an operation to user" })
@Post("operation/add")
async addOperation(@Body() data: IOperation) {
return await this.proxyService.addOperation(data);
}
@ApiOperation({ description: 'get user payments' })
@Get('operation/get/:userName')
async getOperations(@Param('userName') userName: string) {
@ApiOperation({ description: "get user payments" })
@Get("operation/get/:userName")
async getOperations(@Param("userName") userName: string) {
return this.proxyService.getOperations(userName);
}
@ApiOperation({ description: 'get all payments' })
@Get('operation/get-all')
@ApiOperation({ description: "get all payments" })
@Get("operation/get-all")
async getAllOperations() {
return this.proxyService.getAllOperations();
}

View File

@@ -1,12 +1,17 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
export class IProxyUser {
@ApiProperty({ description: 'user name of user to identify them', example: 'username' }) readonly userName!: string;
@ApiProperty({ description: 'some user description if you want', example: 'Description of user' }) readonly description?: string;
@ApiProperty({ description: 'user link to connect to the proxy', example: 'vless://....' }) readonly link!: string;
@ApiProperty({ description: 'telegram user id to connect to user entity', example: '187564' }) readonly user_id?: string;
@ApiProperty({ description: "user name of user to identify them", example: "username" })
readonly userName!: string;
@ApiProperty({ description: "some user description if you want", example: "Description of user" })
readonly description?: string;
@ApiProperty({ description: "user link to connect to the proxy", example: "vless://...." })
readonly link!: string;
@ApiProperty({ description: "telegram user id to connect to user entity", example: "187564" })
readonly user_id?: string;
}
export class IOperation {
@ApiProperty({ description: 'user name of user, that made new operation', example: 'username' }) readonly userName!: string;
@ApiProperty({ description: "user name of user, that made new operation", example: "username" })
readonly userName!: string;
}

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { LibsModule } from 'libs/libs.module';
import { ProxyController } from './proxy.controller';
import { ProxyService } from './proxy.service';
import { Module } from "@nestjs/common";
import { LibsModule } from "libs/libs.module";
import { ProxyController } from "./proxy.controller";
import { ProxyService } from "./proxy.service";
@Module({
imports: [LibsModule],

View File

@@ -1,10 +1,10 @@
import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Payment } from 'libs/database/payment.entity';
import { ProxyUser } from 'libs/database/proxy_user.entity';
import { User } from 'libs/database/user.entity';
import { Repository } from 'typeorm';
import { IOperation, IProxyUser } from './proxy.dto';
import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Payment } from "libs/database/payment.entity";
import { ProxyUser } from "libs/database/proxy_user.entity";
import { User } from "libs/database/user.entity";
import { Repository } from "typeorm";
import { IOperation, IProxyUser } from "./proxy.dto";
@Injectable()
export class ProxyService {
@@ -18,13 +18,16 @@ export class ProxyService {
async newUser(data: IProxyUser) {
try {
if (
(await this.proxyUserRepository.findOne({ where: { userName: data.userName } })) || data.user_id
(await this.proxyUserRepository.findOne({ where: { userName: data.userName } })) ||
data.user_id
? await this.proxyUserRepository.findOne({ where: { user_id: data.user_id } })
: false
)
throw new HttpException('User already exists', HttpStatus.FOUND);
throw new HttpException("User already exists", HttpStatus.FOUND);
const proxyUser = new ProxyUser();
const user = data.user_id ? await this.userRepository.findOne({ where: { id: data.user_id } }) : null;
const user = data.user_id
? await this.userRepository.findOne({ where: { id: data.user_id } })
: null;
if (user) proxyUser.user = user;
proxyUser.description = data.description;
proxyUser.connectDate = new Date();
@@ -37,14 +40,14 @@ export class ProxyService {
throw error;
}
this.logger.debug(`[proxy.newUser] error: ${JSON.stringify(error)}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
async getUser(userName: string) {
try {
const user = await this.proxyUserRepository.findOne({ where: { userName: userName } });
if (!user) throw new HttpException('Not found', HttpStatus.NOT_FOUND);
if (!user) throw new HttpException("Not found", HttpStatus.NOT_FOUND);
return user;
} catch (error) {
if (error instanceof HttpException) {
@@ -52,7 +55,7 @@ export class ProxyService {
throw error;
}
this.logger.debug(`[proxy.getUser] error: ${JSON.stringify(error)}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
@@ -61,14 +64,14 @@ export class ProxyService {
return await this.proxyUserRepository.find();
} catch (error) {
this.logger.debug(`[proxy.getAllUsers] error: ${JSON.stringify(error)}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
async addOperation(data: IOperation) {
try {
const user = await this.proxyUserRepository.findOne({ where: { userName: data.userName } });
if (!user) throw new HttpException('Not found', HttpStatus.NOT_FOUND);
if (!user) throw new HttpException("Not found", HttpStatus.NOT_FOUND);
return await this.paymentRepository.save({ payTime: new Date(), user: user });
} catch (error) {
if (error instanceof HttpException) {
@@ -76,14 +79,17 @@ export class ProxyService {
throw error;
}
this.logger.debug(`[proxy.addOperation] error: ${JSON.stringify(error)}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
async getOperations(userName: string) {
try {
const user = await this.proxyUserRepository.findOne({ where: { userName: userName }, relations: { payments: true } });
if (!user) throw new HttpException('Not found', HttpStatus.NOT_FOUND);
const user = await this.proxyUserRepository.findOne({
where: { userName: userName },
relations: { payments: true },
});
if (!user) throw new HttpException("Not found", HttpStatus.NOT_FOUND);
return user.payments;
} catch (error) {
if (error instanceof HttpException) {
@@ -91,7 +97,7 @@ export class ProxyService {
throw error;
}
this.logger.debug(`[proxy.addOperation] error: ${error}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
@@ -100,7 +106,7 @@ export class ProxyService {
return await this.paymentRepository.find();
} catch (error) {
this.logger.debug(`[proxy.addOperation] error: ${error}`);
throw new HttpException('Bad data', HttpStatus.BAD_REQUEST);
throw new HttpException("Bad data", HttpStatus.BAD_REQUEST);
}
}
}

View File

@@ -1,52 +1,52 @@
import { CacheInterceptor, CacheKey, CacheTTL } from '@nestjs/cache-manager';
import { Body, Controller, Delete, Get, Param, Post, UseInterceptors } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { ICreateBotSettingsProfile, IEditBotSettingsProfile } from './settings.dto';
import { SettingsService } from './settings.service';
import { CacheInterceptor, CacheKey, CacheTTL } from "@nestjs/cache-manager";
import { Body, Controller, Delete, Get, Param, Post, UseInterceptors } from "@nestjs/common";
import { ApiOperation, ApiTags } from "@nestjs/swagger";
import { ICreateBotSettingsProfile, IEditBotSettingsProfile } from "./settings.dto";
import { SettingsService } from "./settings.service";
// Если нужна будет авторизация, для выключения авторизации на конкретном
// const AllowUnathorizedRequest = () => SetMetadata('allowUnathorizedRequest', true);
@ApiTags('Settings')
@Controller('settings')
@ApiTags("Settings")
@Controller("settings")
export class SettingsController {
constructor(private settingsService: SettingsService) {}
@ApiOperation({ description: 'Get settings for bot' })
@ApiOperation({ description: "Get settings for bot" })
@Get()
@CacheKey('settings')
@CacheKey("settings")
@CacheTTL({ ttl: 600 } as any)
@UseInterceptors(CacheInterceptor)
async getSettings() {
return await this.settingsService.getSettings();
}
@ApiOperation({ description: 'Get active settings' })
@Get('active')
@ApiOperation({ description: "Get active settings" })
@Get("active")
async getActiveSettings() {
return await this.settingsService.getActiveSettings();
}
@ApiOperation({ description: 'Get all bot settings profiles' })
@Get('profile')
@ApiOperation({ description: "Get all bot settings profiles" })
@Get("profile")
async getProfiles() {
return await this.settingsService.getProfiles();
}
@ApiOperation({ description: 'Create new settings profile' })
@Post('profile/new')
@ApiOperation({ description: "Create new settings profile" })
@Post("profile/new")
async newProfile(@Body() data: ICreateBotSettingsProfile) {
return await this.settingsService.newProfile(data);
}
@ApiOperation({ description: 'Edit settings profile' })
@Post('profile/edit')
@ApiOperation({ description: "Edit settings profile" })
@Post("profile/edit")
async editProfile(@Body() data: IEditBotSettingsProfile) {
return await this.settingsService.editProfile(data);
}
@ApiOperation({ description: 'Delete settings profile' })
@Delete('profile/delete/:uuid')
async deleteProfile(@Param('uuid') uuid: string) {
@ApiOperation({ description: "Delete settings profile" })
@Delete("profile/delete/:uuid")
async deleteProfile(@Param("uuid") uuid: string) {
return await this.settingsService.deleteProfile(uuid);
}
}

View File

@@ -1,13 +1,21 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
export class ICreateBotSettingsProfile {
@ApiProperty({ description: 'Channel', example: '@neurowoman_test' }) readonly channel: string;
@ApiProperty({ description: 'Post times', example: ['12:00', '14:00'] }) readonly postTimes: string[];
@ApiProperty({ description: "Channel", example: "@neurowoman_test" }) readonly channel: string;
@ApiProperty({ description: "Post times", example: ["12:00", "14:00"] })
readonly postTimes: string[];
}
export class IEditBotSettingsProfile {
@ApiProperty({ description: 'Channel', example: '@neurowoman_test' }) readonly channel: string | undefined;
@ApiProperty({ description: 'Profile uuid', example: '96e7d1b3-20ca-46e8-ac68-e406f79b7eb9' }) readonly uuid: string;
@ApiProperty({ description: 'Post times', example: ['12:00', '14:00'] }) readonly postTimes: string[] | undefined;
@ApiProperty({ description: 'Is active?', example: false }) readonly isActive: boolean | undefined;
@ApiProperty({ description: "Channel", example: "@neurowoman_test" }) readonly channel:
| string
| undefined;
@ApiProperty({ description: "Profile uuid", example: "96e7d1b3-20ca-46e8-ac68-e406f79b7eb9" })
readonly uuid: string;
@ApiProperty({ description: "Post times", example: ["12:00", "14:00"] }) readonly postTimes:
| string[]
| undefined;
@ApiProperty({ description: "Is active?", example: false }) readonly isActive:
| boolean
| undefined;
}

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { LibsModule } from 'libs/libs.module';
import { SettingsController } from './settings.controller';
import { SettingsService } from './settings.service';
import { Module } from "@nestjs/common";
import { LibsModule } from "libs/libs.module";
import { SettingsController } from "./settings.controller";
import { SettingsService } from "./settings.service";
@Module({
imports: [LibsModule],

View File

@@ -1,10 +1,10 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { HttpException, Inject, Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Cache } from 'cache-manager';
import { BotSettings } from 'libs/database/settings.entity';
import { Repository } from 'typeorm';
import { ICreateBotSettingsProfile, IEditBotSettingsProfile } from './settings.dto';
import { CACHE_MANAGER } from "@nestjs/cache-manager";
import { HttpException, Inject, Injectable, Logger } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Cache } from "cache-manager";
import { BotSettings } from "libs/database/settings.entity";
import { Repository } from "typeorm";
import { ICreateBotSettingsProfile, IEditBotSettingsProfile } from "./settings.dto";
@Injectable()
export class SettingsService {
@@ -15,26 +15,29 @@ export class SettingsService {
private readonly logger: Logger = new Logger(SettingsService.name);
async getSettings() {
this.logger.debug('[settings.getSettings]');
this.logger.debug("[settings.getSettings]");
const settings = await this.botSettingsRepository.findOneBy({ isActive: true });
if (settings) return settings;
this.logger.debug(`[settings.getSettings] No active settings found`);
throw new HttpException('No settings found', 404);
throw new HttpException("No settings found", 404);
}
async getActiveSettings() {
this.logger.debug('[settings.getActiveSettings]');
this.logger.debug("[settings.getActiveSettings]");
const settings = await this.botSettingsRepository.findOneBy({ isActive: true });
await this.cacheManager.set('settings', settings, { ttl: 600 } as any);
await this.cacheManager.set("settings", settings, { ttl: 600 } as any);
if (settings) return settings;
this.logger.debug(`[settings.getActiveSettings] No active settings found`);
throw new HttpException('No settings found', 404);
throw new HttpException("No settings found", 404);
}
async newProfile(data: ICreateBotSettingsProfile) {
this.logger.log(`[settings.newProfile] data: ${JSON.stringify(data)}`);
await this.cacheManager.del('settings');
return await this.botSettingsRepository.save({ channel: data.channel, messageTimes: data.postTimes });
await this.cacheManager.del("settings");
return await this.botSettingsRepository.save({
channel: data.channel,
messageTimes: data.postTimes,
});
}
async getProfiles() {
@@ -44,14 +47,14 @@ export class SettingsService {
async editProfile(data: IEditBotSettingsProfile) {
this.logger.log(`[settings.editProfile] data: ${JSON.stringify(data)}`);
await this.cacheManager.del('settings');
await this.cacheManager.del("settings");
const editProfile = await this.botSettingsRepository.findOneBy({ uuid: data.uuid });
if (!editProfile) {
this.logger.debug(`[settings.editProfile] No profile found`);
throw new HttpException('No profile found', 404);
throw new HttpException("No profile found", 404);
}
data.channel ? (editProfile.channel = data.channel) : '';
data.postTimes ? (editProfile.messageTimes = data.postTimes) : '';
data.channel ? (editProfile.channel = data.channel) : "";
data.postTimes ? (editProfile.messageTimes = data.postTimes) : "";
if (data.isActive !== undefined) {
editProfile.isActive = data.isActive;
if (data.isActive) {
@@ -67,11 +70,11 @@ export class SettingsService {
async deleteProfile(profile_uuid: string) {
this.logger.log(`[settings.deleteProfile] uuid: ${profile_uuid}`);
await this.cacheManager.del('settings');
await this.cacheManager.del("settings");
const deleteProfile = await this.botSettingsRepository.findOneBy({ uuid: profile_uuid });
if (!deleteProfile) {
this.logger.debug(`[settings.deleteProfile] No profile found`);
throw new HttpException('No profile found', 404);
throw new HttpException("No profile found", 404);
}
if (deleteProfile.isActive) {
this.logger.debug(`[settings.deleteProfile] Can't delete active profile`);

View File

@@ -1,41 +1,41 @@
import { Body, Controller, Get, Param, Post, Put } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { IGetUser } from './user.dto';
import { UserService } from './user.service';
import { Body, Controller, Get, Param, Post, Put } from "@nestjs/common";
import { ApiOperation, ApiTags } from "@nestjs/swagger";
import { IGetUser } from "./user.dto";
import { UserService } from "./user.service";
@ApiTags('User')
@Controller('user')
@ApiTags("User")
@Controller("user")
export class UserController {
constructor(private userService: UserService) {}
@ApiOperation({
description: 'Create or get user from db',
description: "Create or get user from db",
})
@Post('get')
@Post("get")
async getUser(@Body() data: IGetUser) {
return await this.userService.getUser(data);
}
@ApiOperation({
description: 'Ban user by its telegram id',
description: "Ban user by its telegram id",
})
@Put('ban/:id')
async banUser(@Param('id') id: string) {
@Put("ban/:id")
async banUser(@Param("id") id: string) {
return await this.userService.banUser(id);
}
@ApiOperation({
description: 'Unban user by its telegram id',
description: "Unban user by its telegram id",
})
@Put('unBan/:id')
async unBanUser(@Param('id') id: string) {
@Put("unBan/:id")
async unBanUser(@Param("id") id: string) {
return await this.userService.unBanUser(id);
}
@ApiOperation({
description: 'Get all banned users',
description: "Get all banned users",
})
@Get('banned')
@Get("banned")
async getBannedUsers() {
return await this.userService.getBannedUsers();
}

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
export class IGetUser {
@ApiProperty({ description: 'telegram id', example: '123456' }) readonly id: string;
@ApiProperty({ description: 'telegram username', example: 'durov' }) readonly username?: string;
@ApiProperty({ description: "telegram id", example: "123456" }) readonly id: string;
@ApiProperty({ description: "telegram username", example: "durov" }) readonly username?: string;
}

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { LibsModule } from 'libs/libs.module';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { Module } from "@nestjs/common";
import { LibsModule } from "libs/libs.module";
import { UserController } from "./user.controller";
import { UserService } from "./user.service";
@Module({
imports: [LibsModule],

View File

@@ -1,10 +1,10 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { HttpException, HttpStatus, Inject, Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Cache } from 'cache-manager';
import { User } from 'libs/database/user.entity';
import { Repository } from 'typeorm';
import { IGetUser } from './user.dto';
import { CACHE_MANAGER } from "@nestjs/cache-manager";
import { HttpException, HttpStatus, Inject, Injectable, Logger } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Cache } from "cache-manager";
import { User } from "libs/database/user.entity";
import { Repository } from "typeorm";
import { IGetUser } from "./user.dto";
@Injectable()
export class UserService {
@@ -30,7 +30,7 @@ export class UserService {
return user;
} catch (error) {
this.logger.debug(`[user.getUser] ${JSON.stringify({ error })}`);
throw new HttpException('Internal Server Error', HttpStatus.INTERNAL_SERVER_ERROR);
throw new HttpException("Internal Server Error", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@@ -50,7 +50,7 @@ export class UserService {
return user;
} catch (error) {
this.logger.debug(`[user.banUser] ${JSON.stringify({ error })}`);
throw new HttpException('Error occurred', HttpStatus.INTERNAL_SERVER_ERROR);
throw new HttpException("Error occurred", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@@ -61,7 +61,7 @@ export class UserService {
where: { id: id },
});
if (!user) {
throw new HttpException('No user with this id', HttpStatus.NOT_FOUND);
throw new HttpException("No user with this id", HttpStatus.NOT_FOUND);
}
user = await this.userRepository.save({ id: user.id, banned: false });
return user;
@@ -77,11 +77,14 @@ export class UserService {
async getBannedUsers() {
try {
this.logger.log('[user.getBannedUsers]');
return await this.userRepository.find({ where: { banned: true }, select: { id: true, user_name: true } });
this.logger.log("[user.getBannedUsers]");
return await this.userRepository.find({
where: { banned: true },
select: { id: true, user_name: true },
});
} catch (error) {
this.logger.debug(`[user.getBannedUsers] ${error}`);
throw new HttpException('Error occurred', HttpStatus.INTERNAL_SERVER_ERROR);
throw new HttpException("Error occurred", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

View File

@@ -1,9 +1,9 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
import { Test, TestingModule } from "@nestjs/testing";
import { INestApplication } from "@nestjs/common";
import * as request from "supertest";
import { AppModule } from "./../src/app.module";
describe('AppController (e2e)', () => {
describe("AppController (e2e)", () => {
let app: INestApplication;
beforeEach(async () => {
@@ -15,10 +15,7 @@ describe('AppController (e2e)', () => {
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
it("/ (GET)", () => {
return request(app.getHttpServer()).get("/").expect(200).expect("Hello World!");
});
});

View File

@@ -1 +0,0 @@
{ "dependencies": { "@nestjs/jwt": "^10.2.0" } }