Autoryzacja WebSockets NestJS

// source https://github.com/nestjs/nest/issues/1254

import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common';
import { bindNodeCallback, Observable, of } from 'rxjs';
import { JwtPayload } from './jwt-payload.interface';
import * as jwt from 'jsonwebtoken';
import { catchError, flatMap, map } from 'rxjs/operators';
import { User } from '../user/user.entity';
import { AuthService } from './auth.service';

@Injectable()
export class JwtWsGuard implements CanActivate {
  constructor(
    protected readonly authService: AuthService,
  ) {
  }

  canActivate(
    context: ExecutionContext,
  ): Observable<boolean> {
    const data = context.switchToWs().getData();
    const authHeader = data.headers.authorization;
    const authToken = authHeader.substring(7, authHeader.length);
    const verify: (...args: any[]) => Observable<JwtPayload> = bindNodeCallback(jwt.verify) as any;

    return verify(authToken, process.env.JWT_SECRET_KEY, null)
      .pipe(
        flatMap(jwtPayload => this.authService.validateUser(jwtPayload)),
        catchError(e => {
          console.error(e);
          return of(null);
        }),
        map((user: User | null) => {
          const isVerified = Boolean(user);

          if (!isVerified) {
            throw new UnauthorizedException();
          }

          return isVerified;
        }),
      );
  }
}

// Where on the client you would authenticate by passing 'dummy' headers in the data object like so:

 const websocket = this.websocketService
      .createConnection(`ws://localhost:8080`);
    const jsonWebToken = getJwtSomehow();

    websocket.subscribe(
      (msg) => console.log('message received: ',  msg),
      (err) => console.log(err),
      () => console.log('complete')
    );

    websocket.next({
      event: 'YOUR_EVENT_NAME',
      data: {
        // ...
        headers: {
          authorization: `Bearer ${jsonWebToken}`
        }
      },
    });
Encouraging Eel