Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create bucket session service #183

Merged
merged 1 commit into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/controllers/rest/impl/security/AuthenticationController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Controller, Inject, ProviderScope, Scope } from "@tsed/di";
import { Authenticate, Authorize } from "@tsed/passport";
import { Get, Hidden, Post, Returns, Security } from "@tsed/schema";
import { PlatformResponse, Req, Res, Session, UseBefore } from "@tsed/common";
import { PlatformResponse, Req, Res, UseBefore } from "@tsed/common";
import { StatusCodes } from "http-status-codes";
import { BodyParams } from "@tsed/platform-params";
import { UserModel } from "../../../../model/db/User.model.js";
Expand All @@ -12,13 +12,17 @@ import { CaptchaMiddleWare } from "../../../../middleware/endpoint/CaptchaMiddle
import { DefaultRenderException } from "../../../../model/rest/DefaultRenderException.js";
import type { Request, Response } from "express";
import { AuthenticateBucket } from "../../../../middleware/endpoint/AuthenticateBucket.js";
import { BucketSessionService } from "../../../../services/BucketSessionService.js";

@Controller("/auth")
@Scope(ProviderScope.SINGLETON)
@Hidden()
@(Returns(StatusCodes.FORBIDDEN, DefaultRenderException).Description("If your IP has been blocked"))
export class AuthenticationController extends BaseRestController {
public constructor(@Inject() private usersService: UserService) {
public constructor(
@Inject() private usersService: UserService,
@Inject() private bucketSessionService: BucketSessionService,
) {
super();
}

Expand All @@ -42,9 +46,9 @@ export class AuthenticationController extends BaseRestController {

@Get("/close_bucket")
@Returns(StatusCodes.MOVED_TEMPORARILY)
public closeBucket(@Session() session: Record<string, unknown>, @Res() res: Response): void {
if (session && session.bucket) {
delete session.bucket;
public closeBucket(@Res() res: Response): void {
if (this.bucketSessionService.hasActiveSession()) {
this.bucketSessionService.destroySession();
}
res.redirect("/bucketAccess");
}
Expand Down
12 changes: 8 additions & 4 deletions src/controllers/views/HomeView.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { Get, Hidden, View } from "@tsed/schema";
import { Controller, Inject } from "@tsed/di";
import { Req, Res, Session } from "@tsed/common";
import { Req, Res } from "@tsed/common";
import CaptchaServices from "../../model/constants/CaptchaServices.js";
import { CaptchaManager } from "../../manager/CaptchaManager.js";
import type { Request, Response } from "express";
import { BucketSessionService } from "../../services/BucketSessionService.js";

@Controller("/")
@Hidden()
export class HomeView {
public constructor(@Inject() private captchaManager: CaptchaManager) {}
public constructor(
@Inject() private captchaManager: CaptchaManager,
@Inject() private bucketSessionService: BucketSessionService,
) {}

@Get()
@View("index.ejs")
Expand All @@ -18,8 +22,8 @@ export class HomeView {

@Get("/bucketAccess")
@View("bucketAccess.ejs")
public showBucketLoginPage(@Res() res: Response, @Session() session: Record<string, unknown>): unknown {
if (session.bucket) {
public showBucketLoginPage(@Res() res: Response): unknown {
if (this.bucketSessionService.hasActiveSession()) {
res.redirect("/admin/bucket");
}
const captchaType = this.activeCaptchaService;
Expand Down
16 changes: 8 additions & 8 deletions src/middleware/endpoint/AuthenticateBucket.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { Middleware, MiddlewareMethods } from "@tsed/platform-middlewares";
import { Next, PlatformRequest, Req } from "@tsed/common";
import { Next } from "@tsed/common";
import { Inject } from "@tsed/di";
import { BucketService } from "../../services/BucketService.js";
import { BodyParams } from "@tsed/platform-params";
import { BucketDto } from "../../model/dto/BucketDto.js";
import { BucketAuthenticationException } from "../../model/exceptions/BucketAuthenticationException.js";
import { BucketSessionService } from "../../services/BucketSessionService.js";

@Middleware()
export class AuthenticateBucket implements MiddlewareMethods {
public constructor(@Inject() private bucketService: BucketService) {}
public constructor(
@Inject() private bucketService: BucketService,
@Inject() private bucketSessionService: BucketSessionService,
) {}

public async use(
@Req() request: PlatformRequest,
@BodyParams() bucketDto: BucketDto,
@Next() next: Next,
): Promise<void> {
public async use(@BodyParams() bucketDto: BucketDto, @Next() next: Next): Promise<void> {
if (!bucketDto) {
this.throwError(`Payload missing`);
}
Expand All @@ -28,7 +28,7 @@ export class AuthenticateBucket implements MiddlewareMethods {
}

// we don't want to save the bucket with all the entries into the session, just the token really
request.session.bucket = bucket.bucketToken;
this.bucketSessionService.createSession(bucket);
return next();
}

Expand Down
10 changes: 7 additions & 3 deletions src/middleware/endpoint/AuthoriseBucket.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Middleware, MiddlewareMethods } from "@tsed/platform-middlewares";
import { Next, Session } from "@tsed/common";
import { Next } from "@tsed/common";
import { BucketAuthenticationException } from "../../model/exceptions/BucketAuthenticationException.js";
import { Inject } from "@tsed/di";
import { BucketSessionService } from "../../services/BucketSessionService.js";

@Middleware()
export class AuthoriseBucket implements MiddlewareMethods {
public use(@Session() session: Record<string, unknown>, @Next() next: Next): void {
if (!session || !session.bucket) {
public constructor(@Inject() private bucketSessionService: BucketSessionService) {}

public use(@Next() next: Next): void {
if (!this.bucketSessionService.hasActiveSession()) {
throw new BucketAuthenticationException({
name: "BucketAuthenticationException",
message: "Token is required",
Expand Down
5 changes: 4 additions & 1 deletion src/services/BucketService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { Logger } from "@tsed/logger";
import type { PlatformContext } from "@tsed/common";
import GlobalEnv from "../model/constants/GlobalEnv.js";
import { FileService } from "./FileService.js";
import { BucketSessionService } from "./BucketSessionService.js";

@Service()
export class BucketService {
public constructor(
@Inject() private bucketRepo: BucketRepo,
@Inject() private logger: Logger,
@Inject() private fileService: FileService,
@Inject() private bucketSessionService: BucketSessionService,
) {}

@InjectContext()
Expand Down Expand Up @@ -43,7 +45,7 @@ export class BucketService {
}

private getLoggedInUserBucket(): Promise<BucketModel | null> {
const currentBucketToken: string | null = this.$ctx?.request.session?.bucket ?? null;
const currentBucketToken = this.bucketSessionService.getSessionToken();
if (!currentBucketToken) {
return Promise.resolve(null);
}
Expand All @@ -67,6 +69,7 @@ export class BucketService {
this.logger.error(e);
return false;
}
this.bucketSessionService.destroySession();
return true;
}
}
36 changes: 36 additions & 0 deletions src/services/BucketSessionService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { InjectContext, Service } from "@tsed/di";
import type { PlatformContext } from "@tsed/common";
import { BucketModel } from "../model/db/Bucket.model.js";

@Service()
export class BucketSessionService {
@InjectContext()
protected $ctx?: PlatformContext;

public destroySession(): void {
delete this.getSession()?.bucket;
}

public createSession(bucket: BucketModel): void {
const session = this.getSession();
if (session) {
session.bucket = bucket.bucketToken;
}
}

public getSessionToken(): string | null {
return this.getBucketSession();
}

public hasActiveSession(): boolean {
return this.getSessionToken() !== null;
}

private getBucketSession(): string | null {
return this.$ctx?.request?.session?.bucket ?? null;
}

private getSession(): Record<string, unknown> | null {
return this.$ctx?.request?.session ?? null;
}
}