mirror of
https://github.com/swissmakers/swiss-datashare.git
synced 2026-04-11 10:27:01 +02:00
feat(localization): Added thai language (#231)
* feat(localization): Added Thai translation * Formatted --------- Co-authored-by: Elias Schneider <login@eliasschneider.com>
This commit is contained in:
@@ -33,14 +33,14 @@ export class AuthController {
|
||||
constructor(
|
||||
private authService: AuthService,
|
||||
private authTotpService: AuthTotpService,
|
||||
private config: ConfigService
|
||||
private config: ConfigService,
|
||||
) {}
|
||||
|
||||
@Post("signUp")
|
||||
@Throttle(10, 5 * 60)
|
||||
async signUp(
|
||||
@Body() dto: AuthRegisterDTO,
|
||||
@Res({ passthrough: true }) response: Response
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
) {
|
||||
if (!this.config.get("share.allowRegistration"))
|
||||
throw new ForbiddenException("Registration is not allowed");
|
||||
@@ -50,7 +50,7 @@ export class AuthController {
|
||||
response = this.addTokensToResponse(
|
||||
response,
|
||||
result.refreshToken,
|
||||
result.accessToken
|
||||
result.accessToken,
|
||||
);
|
||||
|
||||
return result;
|
||||
@@ -61,7 +61,7 @@ export class AuthController {
|
||||
@HttpCode(200)
|
||||
async signIn(
|
||||
@Body() dto: AuthSignInDTO,
|
||||
@Res({ passthrough: true }) response: Response
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
) {
|
||||
const result = await this.authService.signIn(dto);
|
||||
|
||||
@@ -69,7 +69,7 @@ export class AuthController {
|
||||
response = this.addTokensToResponse(
|
||||
response,
|
||||
result.refreshToken,
|
||||
result.accessToken
|
||||
result.accessToken,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -81,14 +81,14 @@ export class AuthController {
|
||||
@HttpCode(200)
|
||||
async signInTotp(
|
||||
@Body() dto: AuthSignInTotpDTO,
|
||||
@Res({ passthrough: true }) response: Response
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
) {
|
||||
const result = await this.authTotpService.signInTotp(dto);
|
||||
|
||||
response = this.addTokensToResponse(
|
||||
response,
|
||||
result.refreshToken,
|
||||
result.accessToken
|
||||
result.accessToken,
|
||||
);
|
||||
|
||||
return new TokenDTO().from(result);
|
||||
@@ -113,12 +113,12 @@ export class AuthController {
|
||||
async updatePassword(
|
||||
@GetUser() user: User,
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
@Body() dto: UpdatePasswordDTO
|
||||
@Body() dto: UpdatePasswordDTO,
|
||||
) {
|
||||
const result = await this.authService.updatePassword(
|
||||
user,
|
||||
dto.oldPassword,
|
||||
dto.password
|
||||
dto.password,
|
||||
);
|
||||
|
||||
response = this.addTokensToResponse(response, result.refreshToken);
|
||||
@@ -129,12 +129,12 @@ export class AuthController {
|
||||
@HttpCode(200)
|
||||
async refreshAccessToken(
|
||||
@Req() request: Request,
|
||||
@Res({ passthrough: true }) response: Response
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
) {
|
||||
if (!request.cookies.refresh_token) throw new UnauthorizedException();
|
||||
|
||||
const accessToken = await this.authService.refreshAccessToken(
|
||||
request.cookies.refresh_token
|
||||
request.cookies.refresh_token,
|
||||
);
|
||||
response = this.addTokensToResponse(response, undefined, accessToken);
|
||||
return new TokenDTO().from({ accessToken });
|
||||
@@ -143,7 +143,7 @@ export class AuthController {
|
||||
@Post("signOut")
|
||||
async signOut(
|
||||
@Req() request: Request,
|
||||
@Res({ passthrough: true }) response: Response
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
) {
|
||||
await this.authService.signOut(request.cookies.access_token);
|
||||
response.cookie("access_token", "accessToken", { maxAge: -1 });
|
||||
@@ -176,7 +176,7 @@ export class AuthController {
|
||||
private addTokensToResponse(
|
||||
response: Response,
|
||||
refreshToken?: string,
|
||||
accessToken?: string
|
||||
accessToken?: string,
|
||||
) {
|
||||
if (accessToken)
|
||||
response.cookie("access_token", accessToken, { sameSite: "lax" });
|
||||
|
||||
@@ -21,7 +21,7 @@ export class AuthService {
|
||||
private prisma: PrismaService,
|
||||
private jwtService: JwtService,
|
||||
private config: ConfigService,
|
||||
private emailService: EmailService
|
||||
private emailService: EmailService,
|
||||
) {}
|
||||
|
||||
async signUp(dto: AuthRegisterDTO) {
|
||||
@@ -39,7 +39,7 @@ export class AuthService {
|
||||
});
|
||||
|
||||
const { refreshToken, refreshTokenId } = await this.createRefreshToken(
|
||||
user.id
|
||||
user.id,
|
||||
);
|
||||
const accessToken = await this.createAccessToken(user, refreshTokenId);
|
||||
|
||||
@@ -49,7 +49,7 @@ export class AuthService {
|
||||
if (e.code == "P2002") {
|
||||
const duplicatedField: string = e.meta.target[0];
|
||||
throw new BadRequestException(
|
||||
`A user with this ${duplicatedField} already exists`
|
||||
`A user with this ${duplicatedField} already exists`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ export class AuthService {
|
||||
}
|
||||
|
||||
const { refreshToken, refreshTokenId } = await this.createRefreshToken(
|
||||
user.id
|
||||
user.id,
|
||||
);
|
||||
const accessToken = await this.createAccessToken(user, refreshTokenId);
|
||||
|
||||
@@ -158,7 +158,7 @@ export class AuthService {
|
||||
{
|
||||
expiresIn: "15min",
|
||||
secret: this.config.get("internal.jwtSecret"),
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ export class AuthService {
|
||||
|
||||
return this.createAccessToken(
|
||||
refreshTokenMetaData.user,
|
||||
refreshTokenMetaData.id
|
||||
refreshTokenMetaData.id,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export class AuthTotpService {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private authService: AuthService,
|
||||
private config: ConfigService
|
||||
private config: ConfigService,
|
||||
) {}
|
||||
|
||||
async signInTotp(dto: AuthSignInTotpDTO) {
|
||||
@@ -72,7 +72,7 @@ export class AuthTotpService {
|
||||
await this.authService.createRefreshToken(user.id);
|
||||
const accessToken = await this.authService.createAccessToken(
|
||||
user,
|
||||
refreshTokenId
|
||||
refreshTokenId,
|
||||
);
|
||||
|
||||
return { accessToken, refreshToken };
|
||||
@@ -98,7 +98,7 @@ export class AuthTotpService {
|
||||
const otpURL = totp.keyuri(
|
||||
user.username || user.email,
|
||||
this.config.get("general.appName"),
|
||||
secret
|
||||
secret,
|
||||
);
|
||||
|
||||
await this.prisma.user.update({
|
||||
|
||||
@@ -5,5 +5,5 @@ export const GetUser = createParamDecorator(
|
||||
const request = ctx.switchToHttp().getRequest();
|
||||
const user = request.user;
|
||||
return data ? user?.[data] : user;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -8,7 +8,10 @@ import { PrismaService } from "src/prisma/prisma.service";
|
||||
|
||||
@Injectable()
|
||||
export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
constructor(config: ConfigService, private prisma: PrismaService) {
|
||||
constructor(
|
||||
config: ConfigService,
|
||||
private prisma: PrismaService,
|
||||
) {
|
||||
config.get("internal.jwtSecret");
|
||||
super({
|
||||
jwtFromRequest: JwtStrategy.extractJWT,
|
||||
|
||||
@@ -19,7 +19,7 @@ export class ClamScanService {
|
||||
|
||||
constructor(
|
||||
private fileService: FileService,
|
||||
private prisma: PrismaService
|
||||
private prisma: PrismaService,
|
||||
) {}
|
||||
|
||||
private ClamScan: Promise<NodeClam | null> = new NodeClam()
|
||||
@@ -81,7 +81,7 @@ export class ClamScanService {
|
||||
});
|
||||
|
||||
this.logger.warn(
|
||||
`Share ${shareId} deleted because it contained ${infectedFiles.length} malicious file(s)`
|
||||
`Share ${shareId} deleted because it contained ${infectedFiles.length} malicious file(s)`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export class ConfigController {
|
||||
constructor(
|
||||
private configService: ConfigService,
|
||||
private logoService: LogoService,
|
||||
private emailService: EmailService
|
||||
private emailService: EmailService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
@@ -41,7 +41,7 @@ export class ConfigController {
|
||||
@UseGuards(JwtGuard, AdministratorGuard)
|
||||
async getByCategory(@Param("category") category: string) {
|
||||
return new AdminConfigDTO().fromList(
|
||||
await this.configService.getByCategory(category)
|
||||
await this.configService.getByCategory(category),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ export class ConfigController {
|
||||
@UseGuards(JwtGuard, AdministratorGuard)
|
||||
async updateMany(@Body() data: UpdateConfigDTO[]) {
|
||||
return new AdminConfigDTO().fromList(
|
||||
await this.configService.updateMany(data)
|
||||
await this.configService.updateMany(data),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,9 +66,9 @@ export class ConfigController {
|
||||
@UploadedFile(
|
||||
new ParseFilePipe({
|
||||
validators: [new FileTypeValidator({ fileType: "image/png" })],
|
||||
})
|
||||
}),
|
||||
)
|
||||
file: Express.Multer.File
|
||||
file: Express.Multer.File,
|
||||
) {
|
||||
return await this.logoService.create(file.buffer);
|
||||
}
|
||||
|
||||
@@ -11,12 +11,12 @@ import { PrismaService } from "src/prisma/prisma.service";
|
||||
export class ConfigService {
|
||||
constructor(
|
||||
@Inject("CONFIG_VARIABLES") private configVariables: Config[],
|
||||
private prisma: PrismaService
|
||||
private prisma: PrismaService,
|
||||
) {}
|
||||
|
||||
get(key: `${string}.${string}`): any {
|
||||
const configVariable = this.configVariables.filter(
|
||||
(variable) => `${variable.category}.${variable.name}` == key
|
||||
(variable) => `${variable.category}.${variable.name}` == key,
|
||||
)[0];
|
||||
|
||||
if (!configVariable) throw new Error(`Config variable ${key} not found`);
|
||||
@@ -89,7 +89,7 @@ export class ConfigService {
|
||||
configVariable.type != "text"
|
||||
) {
|
||||
throw new BadRequestException(
|
||||
`Config variable must be of type ${configVariable.type}`
|
||||
`Config variable must be of type ${configVariable.type}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ export class AdminConfigDTO extends ConfigDTO {
|
||||
|
||||
fromList(partial: Partial<AdminConfigDTO>[]) {
|
||||
return partial.map((part) =>
|
||||
plainToClass(AdminConfigDTO, part, { excludeExtraneousValues: true })
|
||||
plainToClass(AdminConfigDTO, part, { excludeExtraneousValues: true }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ export class ConfigDTO {
|
||||
|
||||
fromList(partial: Partial<ConfigDTO>[]) {
|
||||
return partial.map((part) =>
|
||||
plainToClass(ConfigDTO, part, { excludeExtraneousValues: true })
|
||||
plainToClass(ConfigDTO, part, { excludeExtraneousValues: true }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export class LogoService {
|
||||
fs.promises.writeFile(
|
||||
`${IMAGES_PATH}/icons/icon-${size}x${size}.png`,
|
||||
resized,
|
||||
"binary"
|
||||
"binary",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ export class EmailService {
|
||||
await this.getTransporter()
|
||||
.sendMail({
|
||||
from: `"${this.config.get("general.appName")}" <${this.config.get(
|
||||
"smtp.email"
|
||||
"smtp.email",
|
||||
)}>`,
|
||||
to: email,
|
||||
subject,
|
||||
@@ -49,7 +49,7 @@ export class EmailService {
|
||||
shareId: string,
|
||||
creator?: User,
|
||||
description?: string,
|
||||
expiration?: Date
|
||||
expiration?: Date,
|
||||
) {
|
||||
if (!this.config.get("email.enableShareEmailRecipients"))
|
||||
throw new InternalServerErrorException("Email service disabled");
|
||||
@@ -69,8 +69,8 @@ export class EmailService {
|
||||
"{expires}",
|
||||
moment(expiration).unix() != 0
|
||||
? moment(expiration).fromNow()
|
||||
: "in: never"
|
||||
)
|
||||
: "in: never",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -83,13 +83,13 @@ export class EmailService {
|
||||
this.config
|
||||
.get("email.reverseShareMessage")
|
||||
.replaceAll("\\n", "\n")
|
||||
.replaceAll("{shareUrl}", shareUrl)
|
||||
.replaceAll("{shareUrl}", shareUrl),
|
||||
);
|
||||
}
|
||||
|
||||
async sendResetPasswordEmail(recipientEmail: string, token: string) {
|
||||
const resetPasswordUrl = `${this.config.get(
|
||||
"general.appUrl"
|
||||
"general.appUrl",
|
||||
)}/auth/resetPassword/${token}`;
|
||||
|
||||
await this.sendMail(
|
||||
@@ -98,7 +98,7 @@ export class EmailService {
|
||||
this.config
|
||||
.get("email.resetPasswordMessage")
|
||||
.replaceAll("\\n", "\n")
|
||||
.replaceAll("{url}", resetPasswordUrl)
|
||||
.replaceAll("{url}", resetPasswordUrl),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ export class EmailService {
|
||||
this.config
|
||||
.get("email.inviteMessage")
|
||||
.replaceAll("{url}", loginUrl)
|
||||
.replaceAll("{password}", password)
|
||||
.replaceAll("{password}", password),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ export class EmailService {
|
||||
await this.getTransporter()
|
||||
.sendMail({
|
||||
from: `"${this.config.get("general.appName")}" <${this.config.get(
|
||||
"smtp.email"
|
||||
"smtp.email",
|
||||
)}>`,
|
||||
to: recipientEmail,
|
||||
subject: "Test email",
|
||||
|
||||
@@ -28,7 +28,7 @@ export class FileController {
|
||||
@Query() query: any,
|
||||
|
||||
@Body() body: string,
|
||||
@Param("shareId") shareId: string
|
||||
@Param("shareId") shareId: string,
|
||||
) {
|
||||
const { id, name, chunkIndex, totalChunks } = query;
|
||||
|
||||
@@ -39,7 +39,7 @@ export class FileController {
|
||||
data,
|
||||
{ index: parseInt(chunkIndex), total: parseInt(totalChunks) },
|
||||
{ id, name },
|
||||
shareId
|
||||
shareId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ export class FileController {
|
||||
@UseGuards(FileSecurityGuard)
|
||||
async getZip(
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@Param("shareId") shareId: string
|
||||
@Param("shareId") shareId: string,
|
||||
) {
|
||||
const zip = this.fileService.getZip(shareId);
|
||||
res.set({
|
||||
@@ -64,7 +64,7 @@ export class FileController {
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@Param("shareId") shareId: string,
|
||||
@Param("fileId") fileId: string,
|
||||
@Query("download") download = "true"
|
||||
@Query("download") download = "true",
|
||||
) {
|
||||
const file = await this.fileService.get(shareId, fileId);
|
||||
|
||||
|
||||
@@ -18,14 +18,14 @@ export class FileService {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private jwtService: JwtService,
|
||||
private config: ConfigService
|
||||
private config: ConfigService,
|
||||
) {}
|
||||
|
||||
async create(
|
||||
data: string,
|
||||
chunk: { index: number; total: number },
|
||||
file: { id?: string; name: string },
|
||||
shareId: string
|
||||
shareId: string,
|
||||
) {
|
||||
if (!file.id) file.id = crypto.randomUUID();
|
||||
|
||||
@@ -40,7 +40,7 @@ export class FileService {
|
||||
let diskFileSize: number;
|
||||
try {
|
||||
diskFileSize = fs.statSync(
|
||||
`${SHARE_DIRECTORY}/${shareId}/${file.id}.tmp-chunk`
|
||||
`${SHARE_DIRECTORY}/${shareId}/${file.id}.tmp-chunk`,
|
||||
).size;
|
||||
} catch {
|
||||
diskFileSize = 0;
|
||||
@@ -62,7 +62,7 @@ export class FileService {
|
||||
// Check if share size limit is exceeded
|
||||
const fileSizeSum = share.files.reduce(
|
||||
(n, { size }) => n + parseInt(size),
|
||||
0
|
||||
0,
|
||||
);
|
||||
|
||||
const shareSizeSum = fileSizeSum + diskFileSize + buffer.byteLength;
|
||||
@@ -74,23 +74,23 @@ export class FileService {
|
||||
) {
|
||||
throw new HttpException(
|
||||
"Max share size exceeded",
|
||||
HttpStatus.PAYLOAD_TOO_LARGE
|
||||
HttpStatus.PAYLOAD_TOO_LARGE,
|
||||
);
|
||||
}
|
||||
|
||||
fs.appendFileSync(
|
||||
`${SHARE_DIRECTORY}/${shareId}/${file.id}.tmp-chunk`,
|
||||
buffer
|
||||
buffer,
|
||||
);
|
||||
|
||||
const isLastChunk = chunk.index == chunk.total - 1;
|
||||
if (isLastChunk) {
|
||||
fs.renameSync(
|
||||
`${SHARE_DIRECTORY}/${shareId}/${file.id}.tmp-chunk`,
|
||||
`${SHARE_DIRECTORY}/${shareId}/${file.id}`
|
||||
`${SHARE_DIRECTORY}/${shareId}/${file.id}`,
|
||||
);
|
||||
const fileSize = fs.statSync(
|
||||
`${SHARE_DIRECTORY}/${shareId}/${file.id}`
|
||||
`${SHARE_DIRECTORY}/${shareId}/${file.id}`,
|
||||
).size;
|
||||
await this.prisma.file.create({
|
||||
data: {
|
||||
|
||||
@@ -14,7 +14,7 @@ import { ShareService } from "src/share/share.service";
|
||||
export class FileSecurityGuard extends ShareSecurityGuard {
|
||||
constructor(
|
||||
private _shareService: ShareService,
|
||||
private _prisma: PrismaService
|
||||
private _prisma: PrismaService,
|
||||
) {
|
||||
super(_shareService, _prisma);
|
||||
}
|
||||
@@ -24,7 +24,7 @@ export class FileSecurityGuard extends ShareSecurityGuard {
|
||||
|
||||
const shareId = Object.prototype.hasOwnProperty.call(
|
||||
request.params,
|
||||
"shareId"
|
||||
"shareId",
|
||||
)
|
||||
? request.params.shareId
|
||||
: request.params.id;
|
||||
@@ -52,7 +52,7 @@ export class FileSecurityGuard extends ShareSecurityGuard {
|
||||
if (share.security?.maxViews && share.security.maxViews <= share.views) {
|
||||
throw new ForbiddenException(
|
||||
"Maximum views exceeded",
|
||||
"share_max_views_exceeded"
|
||||
"share_max_views_exceeded",
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ export class JobsService {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private reverseShareService: ReverseShareService,
|
||||
private fileService: FileService
|
||||
private fileService: FileService,
|
||||
) {}
|
||||
|
||||
@Cron("0 * * * *")
|
||||
@@ -56,7 +56,7 @@ export class JobsService {
|
||||
|
||||
if (expiredReverseShares.length > 0) {
|
||||
this.logger.log(
|
||||
`Deleted ${expiredReverseShares.length} expired reverse shares`
|
||||
`Deleted ${expiredReverseShares.length} expired reverse shares`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ export class JobsService {
|
||||
|
||||
for (const file of temporaryFiles) {
|
||||
const stats = fs.statSync(
|
||||
`${SHARE_DIRECTORY}/${shareDirectory}/${file}`
|
||||
`${SHARE_DIRECTORY}/${shareDirectory}/${file}`,
|
||||
);
|
||||
const isOlderThanOneDay = moment(stats.mtime)
|
||||
.add(1, "day")
|
||||
|
||||
@@ -23,7 +23,7 @@ export class ReverseShareTokenWithShares extends OmitType(ReverseShareDTO, [
|
||||
return partial.map((part) =>
|
||||
plainToClass(ReverseShareTokenWithShares, part, {
|
||||
excludeExtraneousValues: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import { ReverseShareService } from "./reverseShare.service";
|
||||
export class ReverseShareController {
|
||||
constructor(
|
||||
private reverseShareService: ReverseShareService,
|
||||
private config: ConfigService
|
||||
private config: ConfigService,
|
||||
) {}
|
||||
|
||||
@Post()
|
||||
@@ -44,7 +44,7 @@ export class ReverseShareController {
|
||||
if (!isValid) throw new NotFoundException("Reverse share token not found");
|
||||
|
||||
return new ReverseShareDTO().from(
|
||||
await this.reverseShareService.getByToken(reverseShareToken)
|
||||
await this.reverseShareService.getByToken(reverseShareToken),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ export class ReverseShareController {
|
||||
@UseGuards(JwtGuard)
|
||||
async getAllByUser(@GetUser() user: User) {
|
||||
return new ReverseShareTokenWithShares().fromList(
|
||||
await this.reverseShareService.getAllByUser(user.id)
|
||||
await this.reverseShareService.getAllByUser(user.id),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export class ReverseShareService {
|
||||
constructor(
|
||||
private config: ConfigService,
|
||||
private prisma: PrismaService,
|
||||
private fileService: FileService
|
||||
private fileService: FileService,
|
||||
) {}
|
||||
|
||||
async create(data: CreateReverseShareDTO, creatorId: string) {
|
||||
@@ -19,8 +19,8 @@ export class ReverseShareService {
|
||||
.add(
|
||||
data.shareExpiration.split("-")[0],
|
||||
data.shareExpiration.split(
|
||||
"-"
|
||||
)[1] as moment.unitOfTime.DurationConstructor
|
||||
"-",
|
||||
)[1] as moment.unitOfTime.DurationConstructor,
|
||||
)
|
||||
.toDate();
|
||||
|
||||
@@ -28,7 +28,7 @@ export class ReverseShareService {
|
||||
|
||||
if (globalMaxShareSize < data.maxShareSize)
|
||||
throw new BadRequestException(
|
||||
`Max share size can't be greater than ${globalMaxShareSize} bytes.`
|
||||
`Max share size can't be greater than ${globalMaxShareSize} bytes.`,
|
||||
);
|
||||
|
||||
const reverseShare = await this.prisma.reverseShare.create({
|
||||
|
||||
@@ -27,7 +27,7 @@ export class MyShareDTO extends OmitType(ShareDTO, [
|
||||
|
||||
fromList(partial: Partial<MyShareDTO>[]) {
|
||||
return partial.map((part) =>
|
||||
plainToClass(MyShareDTO, part, { excludeExtraneousValues: true })
|
||||
plainToClass(MyShareDTO, part, { excludeExtraneousValues: true }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ export class ShareDTO {
|
||||
|
||||
fromList(partial: Partial<ShareDTO>[]) {
|
||||
return partial.map((part) =>
|
||||
plainToClass(ShareDTO, part, { excludeExtraneousValues: true })
|
||||
plainToClass(ShareDTO, part, { excludeExtraneousValues: true }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ReverseShareService } from "src/reverseShare/reverseShare.service";
|
||||
export class CreateShareGuard extends JwtGuard {
|
||||
constructor(
|
||||
configService: ConfigService,
|
||||
private reverseShareService: ReverseShareService
|
||||
private reverseShareService: ReverseShareService,
|
||||
) {
|
||||
super(configService);
|
||||
}
|
||||
@@ -21,7 +21,7 @@ export class CreateShareGuard extends JwtGuard {
|
||||
if (!reverseShareTokenId) return false;
|
||||
|
||||
const isReverseShareTokenValid = await this.reverseShareService.isValid(
|
||||
reverseShareTokenId
|
||||
reverseShareTokenId,
|
||||
);
|
||||
|
||||
return isReverseShareTokenValid;
|
||||
|
||||
@@ -16,7 +16,7 @@ export class ShareOwnerGuard implements CanActivate {
|
||||
const request: Request = context.switchToHttp().getRequest();
|
||||
const shareId = Object.prototype.hasOwnProperty.call(
|
||||
request.params,
|
||||
"shareId"
|
||||
"shareId",
|
||||
)
|
||||
? request.params.shareId
|
||||
: request.params.id;
|
||||
|
||||
@@ -14,7 +14,7 @@ import { ShareService } from "src/share/share.service";
|
||||
export class ShareSecurityGuard implements CanActivate {
|
||||
constructor(
|
||||
private shareService: ShareService,
|
||||
private prisma: PrismaService
|
||||
private prisma: PrismaService,
|
||||
) {}
|
||||
|
||||
async canActivate(context: ExecutionContext) {
|
||||
@@ -22,7 +22,7 @@ export class ShareSecurityGuard implements CanActivate {
|
||||
|
||||
const shareId = Object.prototype.hasOwnProperty.call(
|
||||
request.params,
|
||||
"shareId"
|
||||
"shareId",
|
||||
)
|
||||
? request.params.shareId
|
||||
: request.params.id;
|
||||
@@ -44,13 +44,13 @@ export class ShareSecurityGuard implements CanActivate {
|
||||
if (share.security?.password && !shareToken)
|
||||
throw new ForbiddenException(
|
||||
"This share is password protected",
|
||||
"share_password_required"
|
||||
"share_password_required",
|
||||
);
|
||||
|
||||
if (!(await this.shareService.verifyShareToken(shareId, shareToken)))
|
||||
throw new ForbiddenException(
|
||||
"Share token required",
|
||||
"share_token_required"
|
||||
"share_token_required",
|
||||
);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -16,7 +16,7 @@ export class ShareTokenSecurity implements CanActivate {
|
||||
const request: Request = context.switchToHttp().getRequest();
|
||||
const shareId = Object.prototype.hasOwnProperty.call(
|
||||
request.params,
|
||||
"shareId"
|
||||
"shareId",
|
||||
)
|
||||
? request.params.shareId
|
||||
: request.params.id;
|
||||
|
||||
@@ -33,7 +33,7 @@ export class ShareController {
|
||||
@UseGuards(JwtGuard)
|
||||
async getMyShares(@GetUser() user: User) {
|
||||
return new MyShareDTO().fromList(
|
||||
await this.shareService.getSharesByUser(user.id)
|
||||
await this.shareService.getSharesByUser(user.id),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -54,11 +54,11 @@ export class ShareController {
|
||||
async create(
|
||||
@Body() body: CreateShareDTO,
|
||||
@Req() request: Request,
|
||||
@GetUser() user: User
|
||||
@GetUser() user: User,
|
||||
) {
|
||||
const { reverse_share_token } = request.cookies;
|
||||
return new ShareDTO().from(
|
||||
await this.shareService.create(body, user, reverse_share_token)
|
||||
await this.shareService.create(body, user, reverse_share_token),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ export class ShareController {
|
||||
async complete(@Param("id") id: string, @Req() request: Request) {
|
||||
const { reverse_share_token } = request.cookies;
|
||||
return new ShareDTO().from(
|
||||
await this.shareService.complete(id, reverse_share_token)
|
||||
await this.shareService.complete(id, reverse_share_token),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export class ShareController {
|
||||
async getShareToken(
|
||||
@Param("id") id: string,
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
@Body() body: SharePasswordDto
|
||||
@Body() body: SharePasswordDto,
|
||||
) {
|
||||
const token = await this.shareService.getShareToken(id, body.password);
|
||||
response.cookie(`share_${id}_token`, token, {
|
||||
|
||||
@@ -28,7 +28,7 @@ export class ShareService {
|
||||
private config: ConfigService,
|
||||
private jwtService: JwtService,
|
||||
private reverseShareService: ReverseShareService,
|
||||
private clamScanService: ClamScanService
|
||||
private clamScanService: ClamScanService,
|
||||
) {}
|
||||
|
||||
async create(share: CreateShareDTO, user?: User, reverseShareToken?: string) {
|
||||
@@ -46,7 +46,7 @@ export class ShareService {
|
||||
|
||||
// If share is created by a reverse share token override the expiration date
|
||||
const reverseShare = await this.reverseShareService.getByToken(
|
||||
reverseShareToken
|
||||
reverseShareToken,
|
||||
);
|
||||
if (reverseShare) {
|
||||
expirationDate = reverseShare.shareExpiration;
|
||||
@@ -57,8 +57,8 @@ export class ShareService {
|
||||
.add(
|
||||
share.expiration.split("-")[0],
|
||||
share.expiration.split(
|
||||
"-"
|
||||
)[1] as moment.unitOfTime.DurationConstructor
|
||||
"-",
|
||||
)[1] as moment.unitOfTime.DurationConstructor,
|
||||
)
|
||||
.toDate();
|
||||
} else {
|
||||
@@ -134,13 +134,13 @@ export class ShareService {
|
||||
|
||||
if (share.files.length == 0)
|
||||
throw new BadRequestException(
|
||||
"You need at least on file in your share to complete it."
|
||||
"You need at least on file in your share to complete it.",
|
||||
);
|
||||
|
||||
// Asynchronously create a zip of all files
|
||||
if (share.files.length > 1)
|
||||
this.createZip(id).then(() =>
|
||||
this.prisma.share.update({ where: { id }, data: { isZipReady: true } })
|
||||
this.prisma.share.update({ where: { id }, data: { isZipReady: true } }),
|
||||
);
|
||||
|
||||
// Send email for each recipient
|
||||
@@ -150,7 +150,7 @@ export class ShareService {
|
||||
share.id,
|
||||
share.creator,
|
||||
share.description,
|
||||
share.expiration
|
||||
share.expiration,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ export class ShareService {
|
||||
) {
|
||||
await this.emailService.sendMailToReverseShareCreator(
|
||||
share.reverseShare.creator.email,
|
||||
share.id
|
||||
share.id,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ export class ShareService {
|
||||
if (share.security?.maxViews && share.security.maxViews <= share.views) {
|
||||
throw new ForbiddenException(
|
||||
"Maximum views exceeded",
|
||||
"share_max_views_exceeded"
|
||||
"share_max_views_exceeded",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ export class ShareService {
|
||||
{
|
||||
expiresIn: moment(expiration).diff(new Date(), "seconds") + "s",
|
||||
secret: this.config.get("internal.jwtSecret"),
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@ import { OmitType, PartialType } from "@nestjs/swagger";
|
||||
import { UserDTO } from "./user.dto";
|
||||
|
||||
export class UpdateOwnUserDTO extends PartialType(
|
||||
OmitType(UserDTO, ["isAdmin", "password"] as const)
|
||||
OmitType(UserDTO, ["isAdmin", "password"] as const),
|
||||
) {}
|
||||
|
||||
@@ -31,7 +31,7 @@ export class UserDTO {
|
||||
|
||||
fromList(partial: Partial<UserDTO>[]) {
|
||||
return partial.map((part) =>
|
||||
plainToClass(UserDTO, part, { excludeExtraneousValues: true })
|
||||
plainToClass(UserDTO, part, { excludeExtraneousValues: true }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export class UserController {
|
||||
@UseGuards(JwtGuard)
|
||||
async updateCurrentUser(
|
||||
@GetUser() user: User,
|
||||
@Body() data: UpdateOwnUserDTO
|
||||
@Body() data: UpdateOwnUserDTO,
|
||||
) {
|
||||
return new UserDTO().from(await this.userService.update(user.id, data));
|
||||
}
|
||||
@@ -44,7 +44,7 @@ export class UserController {
|
||||
@UseGuards(JwtGuard)
|
||||
async deleteCurrentUser(
|
||||
@GetUser() user: User,
|
||||
@Res({ passthrough: true }) response: Response
|
||||
@Res({ passthrough: true }) response: Response,
|
||||
) {
|
||||
response.cookie("access_token", "accessToken", { maxAge: -1 });
|
||||
response.cookie("refresh_token", "", {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { UpdateUserDto } from "./dto/updateUser.dto";
|
||||
export class UserSevice {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private emailService: EmailService
|
||||
private emailService: EmailService,
|
||||
) {}
|
||||
|
||||
async list() {
|
||||
@@ -46,7 +46,7 @@ export class UserSevice {
|
||||
if (e.code == "P2002") {
|
||||
const duplicatedField: string = e.meta.target[0];
|
||||
throw new BadRequestException(
|
||||
`A user with this ${duplicatedField} already exists`
|
||||
`A user with this ${duplicatedField} already exists`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ export class UserSevice {
|
||||
if (e.code == "P2002") {
|
||||
const duplicatedField: string = e.meta.target[0];
|
||||
throw new BadRequestException(
|
||||
`A user with this ${duplicatedField} already exists`
|
||||
`A user with this ${duplicatedField} already exists`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user