feat: link allow subpath option

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei
2024-08-08 23:50:42 +08:00
parent 1d806fb01c
commit 327d30d675
5 changed files with 28 additions and 14 deletions

View File

@@ -40,7 +40,7 @@ export const generateDefaultConfig: () => IConfig = () => ({
enableComment: true,
enableThrottleGuard: false,
},
friendLinkOptions: { allowApply: true },
friendLinkOptions: { allowApply: true, allowSubPath: false },
backupOptions: {
enable: DEMO_MODE ? false : true,
endpoint: null!,

View File

@@ -3,8 +3,8 @@ import {
ArrayUnique,
IsBoolean,
IsEmail,
IsIP,
IsInt,
IsIP,
IsNotEmpty,
IsOptional,
IsString,
@@ -18,6 +18,7 @@ import { IsAllowedUrl } from '~/decorators/dto/isAllowedUrl'
import { OpenAiSupportedModels } from '../ai/ai.constants'
import { Encrypt } from './configs.encrypt.util'
import {
halfFieldOption,
JSONSchemaArrayField,
JSONSchemaHalfGirdPlainField,
JSONSchemaNumberField,
@@ -25,11 +26,10 @@ import {
JSONSchemaPlainField,
JSONSchemaTextAreaField,
JSONSchemaToggleField,
halfFieldOption,
} from './configs.jsonschema.decorator'
import type { ChatModel } from 'openai/resources'
const SecretField = (target: Object, propertyKey: string | symbol) => {
const SecretField = (target: object, propertyKey: string | symbol) => {
Encrypt(target, propertyKey)
Exclude({ toPlainOnly: true })(target, propertyKey)
}
@@ -261,6 +261,11 @@ export class FriendLinkOptionsDto {
@IsOptional()
@JSONSchemaToggleField('允许申请友链')
allowApply: boolean
@IsBoolean()
@IsOptional()
@JSONSchemaToggleField('允许子路径友链', { description: '例如 /blog 子路径' })
allowSubPath: boolean
}
@JSONSchema({ title: '文本设定' })

View File

@@ -99,6 +99,7 @@ export class LinkController {
if (!(await this.linkService.canApplyLink())) {
throw new ForbiddenException('主人目前不允许申请友链了!')
}
await this.linkService.applyForLink(body)
scheduleManager.schedule(async () => {
await this.linkService.sendToMaster(body.author, body)

View File

@@ -1,5 +1,6 @@
import { URL } from 'node:url'
import { modelOptions, prop } from '@typegoose/typegoose'
import { Transform } from 'class-transformer'
import {
IsEmail,
IsEnum,
@@ -9,8 +10,6 @@ import {
MaxLength,
} from 'class-validator'
import { modelOptions, prop } from '@typegoose/typegoose'
import { BaseModel } from '~/shared/model/base.model'
export enum LinkType {
@@ -51,9 +50,6 @@ export class LinkModel extends BaseModel {
required: true,
trim: true,
unique: true,
set(val) {
return new URL(val).origin
},
})
@IsUrl(
{ require_protocol: true, protocols: ['https'] },

View File

@@ -1,18 +1,20 @@
import { URL } from 'node:url'
import {
BadRequestException,
Injectable,
Logger,
NotFoundException,
UnprocessableEntityException,
} from '@nestjs/common'
import { BusinessEvents, EventScope } from '~/constants/business-event.constant'
import { isDev } from '~/global/env.global'
import { EmailService } from '~/processors/helper/helper.email.service'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { HttpService } from '~/processors/helper/helper.http.service'
import { InjectModel } from '~/transformers/model.transformer'
import { scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils'
import { ConfigsService } from '../configs/configs.service'
import { UserService } from '../user/user.service'
import { LinkApplyEmailType } from './link-mail.enum'
@@ -36,6 +38,8 @@ export class LinkService {
return this.linkModel
}
async applyForLink(model: LinkModel) {
const { allowSubPath } = await this.configsService.get('friendLinkOptions')
const existedDoc = await this.model
.findOne({
$or: [{ url: model.url }, { name: model.name }],
@@ -66,8 +70,16 @@ export class LinkService {
.lean()
}
} else {
const url = new URL(model.url)
const pathname = url.pathname
if (pathname !== '/' && !allowSubPath) {
throw new UnprocessableEntityException('管理员当前禁用了子路径友链申请')
}
nextModel = await this.model.create({
...model,
url: allowSubPath ? `${url.origin}${url.pathname}` : url.origin,
type: LinkType.Friend,
state: LinkState.Audit,
})
@@ -134,7 +146,7 @@ export class LinkService {
}
const { enable } = await this.configs.get('mailOptions')
if (!enable || isDev) {
console.log(`
console.info(`
To: ${model.email}
你的友链已通过
站点标题:${model.name}
@@ -152,7 +164,7 @@ export class LinkService {
async sendToMaster(authorName: string, model: LinkModel) {
const enable = (await this.configs.get('mailOptions')).enable
if (!enable || isDev) {
console.log(`来自 ${authorName} 的友链请求:
console.info(`来自 ${authorName} 的友链请求:
站点标题:${model.name}
站点网站:${model.url}
站点描述:${model.description}`)