Перейти к содержимому
docs.
WORKSPACE

Документации проектов

Открыть каталог проектов
Localzet ServerАсинхронный PHP-серверTriangleФреймворк и компонентыMIX IDИдентификация и интеграцииHack APIПубличные API хакатонаACNПроект и компонентыUserlay / UserNetПроект и компоненты✓AxiomПроект и компонентыМесседжинг через почтуПроект и компонентыLWT / JWT / JOSEПроект и компонентыФинансовая аналитика KimaiПроект и компонентыМультипарадигмальная БДПроект и компонентыZorin PlatformПроект и компонентыZorin TrustПроект и компонентыFloraScope / VegwatchПроект и компонентыaegis-qДокументация проектаaevumdbДокументация проектаauditДокументация проектаauto-invest-managerАвтотрейдерcaine-companionДокументация проектаcertbot-cloudflareДокументация проектаClusterLocalzet Server / ClustercmdveilДокументация проектаConsolePHP CLICronБиблиотеки Localzet Serverdata-connectorДокументация проектаdevice-controlDevice Controlenn-projectДокументация проектаEventsБиблиотеки Localzet ServerflowsintДокументация проектаforgeДокументация проектаHttpClientБиблиотеки Localzet ServerinterpreterСобственный языкinvariaДокументация проектаkeynotesДокументация проектаknotrouteKnotroutelaravel-personal-analyticsДокументация проектаlocalzet-osДокументация проектаmeridianДокументация проектаMQTTБиблиотеки Localzet Servernano-kernelСобственная ОСNoterДокументация проектаpersonal-analyticsДокументация проектаProxyБиблиотеки Localzet ServerPSRБиблиотеки Localzet ServerPSR-7Библиотеки Localzet Serverrschs-monitorДокументация проектаsemsealДокументация проектаshardsealДокументация проектаSocketIOБиблиотеки Localzet ServerSOCKS5Библиотеки Localzet Serverstandalone-analyticsДокументация проектаstatic-php-cliДокументация проектаStorageБиблиотеки Localzet ServersutureДокументация проектаtempoweaveДокументация проектаttsСинтез речиTunnelБиблиотеки Localzet Serverui-kitUI KitvesperДокументация проектаWebAnalyzerWebAnalyzerzorin-access-brokerДокументация проектаzorin-authority-brokerДокументация проектаzorin-authority-sdk-phpДокументация проектаzorin-authority-sdk-pythonДокументация проектаzorin-authority-sdk-tsДокументация проектаzorin-client-intelДокументация проектаzorin-device-core-aospДокументация проектаzorin-host-agentДокументация проектаzorin-native-labДокументация проектаzorin-nodeДокументация проектаzorin-opsДокументация проектаdonstu-python-sdkДокументация проектаfloortraceFloortraceserver-rsLocalzet Server / Cluster
Каталог
Документация/Userlay / UserNet

aura-node — API

src/app.module.ts

@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: '.env',
validate: (config) => validateEnvConfig<Env>(configSchema, config),
}),
XtlsSdkNestjsModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
ip: configService.getOrThrow<string>('XTLS_IP'),
port: configService.getOrThrow<string>('XTLS_PORT'),
}),
}),
SupervisordNestjsModule.forRootAsync({
imports: [],
inject: [],
useFactory: () => ({
host: 'http://127.0.0.1:61002',
options: {
username: 'aura',
password: 'JNBFdjbEDbDBFbJH',
},
}),
}),
AuraNodeModules,
InternalModule,
JwtModule.registerAsync(getJWTConfig()),
],
providers: [JwtStrategy],
exports: [],
})
export class AppModule {}

src/common/config/app-config/config.schema.ts

export type ConfigSchema = z.infer<typeof configSchema>;

src/common/config/app-config/config.schema.ts

export class Env extends createZodDto(configSchema) {}

src/common/exception/http-exeception-with-error-code.type.ts

export class HttpExceptionWithErrorCodeType extends HttpException {
errorCode: string;
constructor(message: string, errorCode: string, statusCode: number) {
super(message, statusCode);
this.errorCode = errorCode;
}
}

src/common/exception/httpException.filter.ts

@Catch(HttpExceptionWithErrorCodeType, ZodValidationException)
export class HttpExceptionFilter implements ExceptionFilter {
private readonly logger = new Logger(HttpExceptionFilter.name);
catch(exception: HttpExceptionWithErrorCodeType | ZodValidationException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception?.getStatus();
let errorMessage: string | string[];
let errorCode = 'E000';
if (status === HttpStatus.FORBIDDEN) {
errorMessage = 'Forbidden';
} else {
errorMessage = exception.message;
if (exception instanceof HttpExceptionWithErrorCodeType) {
errorCode = exception.errorCode;
}
}
if (exception instanceof ZodValidationException) {
this.logger.error(exception.getResponse());
response.status(status).json(exception.getResponse());
} else {
this.logger.error({
timestamp: new Date().toISOString(),
code: errorCode,
path: request.url,
message: errorMessage,
});
response.status(status).json({
timestamp: new Date().toISOString(),
path: request.url,
message: errorMessage,
errorCode,
});
}
}
}

src/common/exception/not-found-exception.filter.ts

@Catch(NotFoundException)
export class NotFoundExceptionFilter implements ExceptionFilter {
catch(exception: NotFoundException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
response.socket?.destroy();
}
}

src/common/guards/jwt-guards/def-jwt-guard.ts

export class JwtDefaultGuard extends AuthGuard('registeredUserJWT') {
private readonly logger = new Logger(JwtDefaultGuard.name);
handleRequest(err: any, user: any, info: any, context: ExecutionContext) {
if (info instanceof Error || err || !user) {
const response = context.switchToHttp().getResponse();
this.logger.debug(`${JSON.stringify(context.switchToHttp().getRequest().headers)}`);
this.logger.error(
`Неверный SSL_CERT или JWT! Запрос отклонён. URL: ${context.switchToHttp().getRequest().url}, IP: ${context.switchToHttp().getRequest().ip}`,
);
response.socket?.destroy();
throw new UnauthorizedException('Не авторизован');
}
return user;
}
}

src/common/guards/jwt-guards/strategies/validate-token.ts

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'registeredUserJWT') {
constructor(configService: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: configService.getOrThrow<string>('JWT_PUBLIC_KEY'),
algorithms: ['RS256'],
});
}
async validate(JWTPrivatePayload: unknown): Promise<unknown> {
return JWTPrivatePayload;
}
}

src/common/guards/request-port-guard/request-port.guard.ts

@Injectable()
export class PortGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const port =
this.reflector.get<number>('port', context.getHandler()) ||
this.reflector.get<number>('port', context.getClass());
if (!port) return true;
const req = context.switchToHttp().getRequest();
const addressInfo = req.socket.server.address();
const isInternal = addressInfo?.port === port;
const isInternalIp = addressInfo?.address === '127.0.0.1';
if (!isInternal || !isInternalIp) {
const response = context.switchToHttp().getResponse();
response.socket?.destroy();
throw new UnauthorizedException('Не авторизован');
}
return isInternal;
}
}

src/common/helpers/can-parse-json.ts

export function canParseJSON(jsonString: string): boolean

src/common/helpers/error-handler-with-null.helper.ts

export function errorHandlerWithNull<T>(response: ICommandResponse<T>): null | T

src/common/helpers/error-handler.helper.ts

export function errorHandler<T>(response: ICommandResponse<T>): T

src/common/types/command-response.type.ts

export interface ICommandResponse<T> {
code?: string;
isOk: boolean;
message?: string;
response?: T;
}

src/common/types/converter.interface.ts

export interface IConverter<T, U> {
fromEntitiesToPrismaModels(entities: T[]): U[];
fromEntityToPrismaModel(entity: T): U;
fromPrismaModelsToEntities(prismaModels: U[]): T[];
fromPrismaModelToEntity(prismaModel: U): T;
}

src/common/types/crud-port.ts

export interface ICrud<ENTITY> {
create: (entity: ENTITY) => Promise<ENTITY>;
deleteByUUID: (uuid: string) => Promise<boolean>;
findByCriteria: (entity: Partial<ENTITY>) => Promise<ENTITY[]>;
findByUUID: (uuid: string) => Promise<ENTITY | null>;
update: (entity: ENTITY) => Promise<ENTITY | null>;
}

src/common/utils/decode-node-payload/decode-node-payload.ts

export function parseNodePayload(): INodePayload

src/common/utils/decode-node-payload/decode-node-payload.ts

export function parseNodePayloadFromConfigService(sslCert: string): INodePayload

src/common/utils/get-start-message.ts

export async function getStartMessage(
appPort: number,
internalPort: number,
app: INestApplication,
)

src/common/utils/get-system-stats/get-system-stats.interface.ts

export interface ISystemStats {
cpuCores: number;
cpuModel: string;
memoryTotal: string;
}

src/common/utils/get-system-stats/get-system-stats.ts

export async function getSystemStats(): Promise<ISystemStats>

src/common/utils/is-development.ts

export function isDevelopment(): boolean

src/common/utils/sleep.ts

export function sleep(ms: number): Promise<void>

src/common/utils/validate-env-config.ts

export function validateEnvConfig<T>(schema: z.ZodType, config: Record<string, unknown>): T

src/modules/aura-node.modules.ts

@Module({
imports: [StatsModule, XrayModule, HandlerModule, VisionModule],
providers: [],
})
export class AuraNodeModules {}

src/modules/handler/dtos/add-user.dto.ts

export class AddUserRequestDto extends createZodDto(AddUserCommand.RequestSchema) {}

src/modules/handler/dtos/add-user.dto.ts

export class AddUserResponseDto extends createZodDto(AddUserCommand.ResponseSchema) {}

src/modules/handler/dtos/get-inbound-users-count.dto.ts

export class GetInboundUsersCountRequestDto extends createZodDto(
GetInboundUsersCountCommand.RequestSchema,
) {}

src/modules/handler/dtos/get-inbound-users-count.dto.ts

export class GetInboundUsersCountResponseDto extends createZodDto(
GetInboundUsersCountCommand.ResponseSchema,
) {}

src/modules/handler/dtos/get-inbound-users.dto.ts

export class GetInboundUsersRequestDto extends createZodDto(GetInboundUsersCommand.RequestSchema) {}

src/modules/handler/dtos/get-inbound-users.dto.ts

export class GetInboundUsersResponseDto extends createZodDto(
GetInboundUsersCommand.ResponseSchema,
) {}

src/modules/handler/dtos/remove-user.dto.ts

export class RemoveUserRequestDto extends createZodDto(RemoveUserCommand.RequestSchema) {}

src/modules/handler/dtos/remove-user.dto.ts

export class RemoveUserResponseDto extends createZodDto(RemoveUserCommand.ResponseSchema) {}

src/modules/handler/handler.controller.ts

@UseFilters(HttpExceptionFilter)
@UseGuards(JwtDefaultGuard)
@Controller(HANDLER_CONTROLLER)
export class HandlerController {
constructor(private readonly handlerService: HandlerService) {}
@Post(HANDLER_ROUTES.ADD_USER)
public async addUser(@Body() body: AddUserRequestDto): Promise<AddUserResponseDto> {
const response = await this.handlerService.addUser(body);
const data = errorHandler(response);
return {
response: data,
};
}
@Post(HANDLER_ROUTES.GET_INBOUND_USERS)
public async getInboundUsers(
@Body() body: GetInboundUsersRequestDto,
): Promise<GetInboundUsersResponseDto> {
const response = await this.handlerService.getInboundUsers(body.tag);
const data = errorHandler(response);
return {
response: data,
};
}
@Post(HANDLER_ROUTES.REMOVE_USER)
public async removeUser(@Body() body: RemoveUserRequestDto): Promise<RemoveUserResponseDto> {
const response = await this.handlerService.removeUser(body);
const data = errorHandler(response);
return {
response: data,
};
}
@Post(HANDLER_ROUTES.GET_INBOUND_USERS_COUNT)
public async getInboundUsersCount(
@Body() body: GetInboundUsersCountRequestDto,
): Promise<GetInboundUsersCountResponseDto> {
const response = await this.handlerService.getInboundUsersCount(body.tag);
const data = errorHandler(response);
return {
response: data,
};
}
}

src/modules/handler/handler.module.ts

@Module({
imports: [XrayModule],
controllers: [HandlerController],
providers: [HandlerService],
})
export class HandlerModule {}

src/modules/handler/interfaces/add-user.interface.ts

export interface TAddUserRequest {
data: Array<
| {
cipherType: CipherType;
ivCheck: boolean;
level: number;
password: string;
tag: string;
type: 'shadowsocks';
username: string;
}
| {
flow: '' | 'xtls-rprx-vision';
level: number;
tag: string;
type: 'vless';
username: string;
uuid: string;
}
| {
http_password: string;
http_username: string;
level: number;
tag: string;
type: 'http';
username: string;
}
| {
key: string;
level: number;
tag: string;
type: 'shadowsocks2022';
username: string;
}
| {
level: number;
password: string;
tag: string;
type: 'trojan';
username: string;
}
| {
level: number;
socks_password: string;
socks_username: string;
tag: string;
type: 'socks';
username: string;
}
>;
}

src/modules/handler/interfaces/remove-user.interface.ts

export interface IRemoveUserRequest {
username: string;
}

src/modules/handler/models/add-user.response.model.ts

export class AddUserResponseModel {
success: boolean;
error: null | string;
constructor(success: boolean, error: null | string) {
this.success = success;
this.error = error;
}
}

src/modules/handler/models/get-inbound-users-count.response.model.ts

export class GetInboundUsersCountResponseModel {
public count: number;
constructor(count: number) {
this.count = count;
}
}

src/modules/handler/models/get-inbound-users.response.model.ts

export class GetInboundUsersResponseModel {
public users: IInboundUser[];
constructor(users: IInboundUser[]) {
this.users = users.map((user) => ({
username: user.username,
level: user.level,
protocol: user.protocol,
}));
}
}

src/modules/handler/models/interfaces/inbound-user.interface.ts

export interface IInboundUser {
level: number;
protocol: string;
username: string;
}

src/modules/handler/models/remove-user.response.model.ts

export class RemoveUserResponseModel {
success: boolean;
error: null | string;
constructor(success: boolean, error: null | string) {
this.success = success;
this.error = error;
}
}

src/modules/internal/internal.controller.ts

@OnPort(XRAY_INTERNAL_API_PORT)
@UseFilters(HttpExceptionFilter)
@UseGuards(PortGuard)
@Controller(XRAY_INTERNAL_API_CONTROLLER)
export class InternalController {
constructor(private readonly internalService: InternalService) {}
@Get(XRAY_INTERNAL_API_PATH)
public async getXrayConfig(): Promise<Record<string, unknown>> {
try {
const config = await this.internalService.getXrayConfig();
return config;
} catch {
return {};
}
}
}

src/modules/internal/internal.module.ts

@Global()
@Module({
imports: [],
providers: [InternalService],
controllers: [InternalController],
exports: [InternalService],
})
export class InternalModule {}

src/modules/internal/internal.service.ts

@Injectable()
export class InternalService {
private readonly logger = new Logger(InternalService.name);
private xrayConfig: null | Record<string, unknown> = null;
constructor() {}
public async getXrayConfig(): Promise<Record<string, unknown>> {
if (!this.xrayConfig) {
return {};
}
return this.xrayConfig;
}
public setXrayConfig(config: Record<string, unknown>): void {
this.logger.debug('Установка новой конфигурации Xray');
this.xrayConfig = config;
}
}