* feat(reverse-share): optional simplified interface for reverse sharing. issue #155. * chore: Remove useless form validation. * feat: Share Ready modal adds a prompt that an email has been sent to the reverse share creator. * fix: Simplified reverse shared interface elements lack spacing when not logged in. * fix: Share Ready modal prompt contrast is too low in dark mode. * feat: add public access options to reverse share. * feat: remember reverse share simplified and publicAccess options in cookies. * style: npm run format. * chore(i18n): Improve translation. Co-authored-by: Elias Schneider <login@eliasschneider.com> Update frontend/src/i18n/translations/en-US.ts Co-authored-by: Elias Schneider <login@eliasschneider.com> Update frontend/src/i18n/translations/en-US.ts Co-authored-by: Elias Schneider <login@eliasschneider.com> chore(i18n): Improve translation. * chore: Improved variable naming. * chore(i18n): Improve translation. x2. * fix(backend/shares): Misjudged the permission of the share of the reverse share.
68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
import {
|
|
ExecutionContext,
|
|
ForbiddenException,
|
|
Injectable,
|
|
NotFoundException,
|
|
} from "@nestjs/common";
|
|
import { Request } from "express";
|
|
import * as moment from "moment";
|
|
import { PrismaService } from "src/prisma/prisma.service";
|
|
import { ShareSecurityGuard } from "src/share/guard/shareSecurity.guard";
|
|
import { ShareService } from "src/share/share.service";
|
|
import { ConfigService } from "src/config/config.service";
|
|
|
|
@Injectable()
|
|
export class FileSecurityGuard extends ShareSecurityGuard {
|
|
constructor(
|
|
private _shareService: ShareService,
|
|
private _prisma: PrismaService,
|
|
_config: ConfigService,
|
|
) {
|
|
super(_shareService, _prisma, _config);
|
|
}
|
|
|
|
async canActivate(context: ExecutionContext) {
|
|
const request: Request = context.switchToHttp().getRequest();
|
|
|
|
const shareId = Object.prototype.hasOwnProperty.call(
|
|
request.params,
|
|
"shareId",
|
|
)
|
|
? request.params.shareId
|
|
: request.params.id;
|
|
|
|
const shareToken = request.cookies[`share_${shareId}_token`];
|
|
|
|
const share = await this._prisma.share.findUnique({
|
|
where: { id: shareId },
|
|
include: { security: true },
|
|
});
|
|
|
|
// If there is no share token the user requests a file directly
|
|
if (!shareToken) {
|
|
if (
|
|
!share ||
|
|
(moment().isAfter(share.expiration) &&
|
|
!moment(share.expiration).isSame(0))
|
|
) {
|
|
throw new NotFoundException("File not found");
|
|
}
|
|
|
|
if (share.security?.password)
|
|
throw new ForbiddenException("This share is password protected");
|
|
|
|
if (share.security?.maxViews && share.security.maxViews <= share.views) {
|
|
throw new ForbiddenException(
|
|
"Maximum views exceeded",
|
|
"share_max_views_exceeded",
|
|
);
|
|
}
|
|
|
|
await this._shareService.increaseViewCount(share);
|
|
return true;
|
|
} else {
|
|
return super.canActivate(context);
|
|
}
|
|
}
|
|
}
|