@nestjs/common#NestMiddleware TypeScript Examples

The following examples show how to use @nestjs/common#NestMiddleware. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: require-ssl.middleware.ts    From ironfish-api with Mozilla Public License 2.0 6 votes vote down vote up
@Injectable()
export class RequireSslMiddleware implements NestMiddleware {
  constructor(private readonly config: ApiConfigService) {}

  use(req: Request, _res: Response, next: NextFunction): void {
    if (
      this.config.get<string>('NODE_ENV') !== 'development' &&
      req.headers['x-forwarded-proto'] !== 'https'
    ) {
      throw new ForbiddenException({
        message: '"https" is required to access the Iron Fish API',
      });
    }
    next();
  }
}
Example #2
Source File: mikro-orm.middleware.ts    From nestjs with MIT License 6 votes vote down vote up
@Injectable()
export class MikroOrmMiddleware implements NestMiddleware {

  constructor(private readonly orm: MikroORM) {}

  use(req: unknown, res: unknown, next: (...args: any[]) => void) {
    RequestContext.create(this.orm.em, next);
  }

}
Example #3
Source File: multiple-mikro-orm.middleware.ts    From nestjs with MIT License 6 votes vote down vote up
@Injectable()
export class MultipleMikroOrmMiddleware implements NestMiddleware {

  constructor(@Inject('MikroORMs') private readonly orm: MikroORM[]) {}

  use(req: unknown, res: unknown, next: (...args: any[]) => void) {
    RequestContext.create(this.orm.map(orm => orm.em), next);
  }

}
Example #4
Source File: tracing.middleware.ts    From nest-xray with MIT License 6 votes vote down vote up
@Injectable()
export class HttpTracingMiddleware implements NestMiddleware {
  private readonly middleware: RequestHandler;

  constructor(private readonly tracingService: TracingService) {
    this.middleware = this.tracingService.tracingMiddleware();
  }

  public use(req: any, res: any, next: () => void) {
    this.middleware(req, res, () => {
      if (req.segment) {
        // AWS X-Ray does not remove the query string from incoming requests
        req.segment.http.request.url = this.patchSegmentURL(req);

        this.tracingService.setRootSegment(req.segment);
      }
      next();
    });
  }

  private patchSegmentURL(req: PatchSegmentURLRequest): string {
    const {
      segment: {
        http: {
          request: { url: xrayParsedUrl },
        },
      },
    } = req;

    // xrayParsedUrl is relative and requires a generic base
    const xrayUrl = new URL(xrayParsedUrl, "https://example.com/");

    // Remove SearchParams/QueryParams
    // See #140
    xrayUrl.search = "";

    return xrayUrl.href;
  }
}
Example #5
Source File: api-token.middleware.ts    From relate with GNU General Public License v3.0 6 votes vote down vote up
@Injectable()
export class ApiTokenMiddleware implements NestMiddleware {
    constructor(@Inject(SystemProvider) private readonly systemProvider: SystemProvider) {}

    async use(req: Request, res: Response, next: NextFunction) {
        if (_.startsWith(req.path, HEALTH_BASE_ENDPOINT) || _.startsWith(req.path, STATIC_APP_BASE_ENDPOINT)) {
            next();
            return;
        }

        const clientId = getRequestToken(req, CLIENT_ID_HEADER) || '';
        const apiToken = getRequestToken(req, API_TOKEN_HEADER) || '';
        const environment = await this.systemProvider.getEnvironment();

        if (!environment.requiresAPIToken) {
            next();
            return;
        }

        const origin = req.get('origin');
        // Use the client URL otherwise fallback to the Relate server URL.
        // Requests coming from files might contain either 'null' or 'file://' in the Origin header.
        const requestUrl = origin && origin !== 'null' && new URL(origin).host ? origin : environment.httpOrigin;
        const requestHost = new URL(requestUrl).host;

        try {
            await environment.verifyAPIToken(requestHost, clientId, apiToken);
            next();
        } catch (e) {
            res.clearCookie(CLIENT_ID_HEADER);
            res.clearCookie(API_TOKEN_HEADER);
            res.sendStatus(401);
        }
    }
}
Example #6
Source File: auth-token.middleware.ts    From relate with GNU General Public License v3.0 6 votes vote down vote up
@Injectable()
export class AuthTokenMiddleware implements NestMiddleware {
    constructor(@Inject(SystemProvider) private readonly systemProvider: SystemProvider) {}

    async use(req: Request, res: Response, next: NextFunction) {
        if (_.startsWith(req.path, AUTHENTICATION_BASE_ENDPOINT) || _.startsWith(req.path, HEALTH_BASE_ENDPOINT)) {
            next();
            return;
        }

        const authToken = getRequestToken(req, AUTH_TOKEN_HEADER);
        const environment = await this.systemProvider.getEnvironment();

        try {
            await environment.verifyAuthToken(authToken);
            next();
        } catch (e) {
            res.clearCookie(AUTH_TOKEN_HEADER);

            if (req.method !== 'GET') {
                res.sendStatus(401);
                return;
            }

            const {authUrl} = await environment.login(req.url);

            res.redirect(authUrl);
        }
    }
}
Example #7
Source File: local.strategy.ts    From radiopanel with GNU General Public License v3.0 6 votes vote down vote up
@Injectable()
export class LocalStrategyProvider implements NestMiddleware {
	constructor(
		private userService: UserService
	) {}

	public async use(req: Request, res: Response, next: NextFunction) {
		const strategy = await this.getConfiguration();

		passport.authenticate(strategy)(req, res, next);
	}

	private async getConfiguration(): Promise<LocalStrategy> {
		return new LocalStrategy(
			{
				usernameField: 'email'
			},
			async (email: string, password: string, done: Function): Promise<any> => {
				const user = await this.userService.findOne({ email });

				if (!user) {
					done(null, false, { message: 'Please make sure all your details are correct' });
				}

				const isValidUser = await User.comparePassword(user, password);

				if (!isValidUser) {
					done(null, false, { message: 'Please make sure all your details are correct' });
				}

				done(null, await this.userService.findOne({ uuid: user.uuid }))
			}
		);
	}
}
Example #8
Source File: auth.middleware.ts    From NextJS-NestJS-GraphQL-Starter with MIT License 6 votes vote down vote up
@Injectable()
export class AuthMiddleware implements NestMiddleware {
  constructor(private authService: AuthService) {}

  async use(
    req: Request & { user: string; ip: string },
    res: Response,
    next: Function,
  ) {
    const token = get(req, 'cookies.token');
    if (!token) {
      return next();
    }

    const refreshToken = await this.authService.getSession({ token });
    req.user = get(refreshToken, 'user', null);

    return next();
  }
}
Example #9
Source File: api-token-check.middleware.ts    From nest-js-quiz-manager with MIT License 5 votes vote down vote up
export class ApiTokenCheckMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    if (req.headers['api-token'] !== 'my-token') {
      throw new ApiTokenPaymentException();
    }
    next();
  }
}
Example #10
Source File: preAuth.middleware.ts    From edu-server with MIT License 5 votes vote down vote up
@Injectable()
export class PreauthMiddleware implements NestMiddleware {
  constructor(@InjectModel('User') private readonly userModel: Model<User>) {}
  use(req: Request, res: Response, next: NextFunction) {
    const token = req.headers.authorization;
    if (token && token != null && token != '' && token.length > 0) {
      admin
        .auth()
        .verifyIdToken(token.replace('Bearer ', ''))
        .then(async (decodedToken) => {
          const { email, uid, picture } = decodedToken;

          const userExists = await this.userModel
            .findOne({ email: email })
            .lean();

          let role;

          if (userExists) {
            role = userExists.role || Role.STUDENT;
            await this.userModel.updateOne(
              { email: userExists.email },
              {
                log_in_time: new Date().toString(),
              },
            );
          } else {
            const newUser = new this.userModel({
              email,
              fid: uid,
              role: Role.STUDENT,
              photoUrl: picture,
              log_in_time: ' ',
            });
            await newUser.save();
            role = Role.STUDENT;
            console.log(role);
          }

          const user = {
            email: email,
            fId: uid,
            role: role,
          };

          req['user'] = user;
          next();
        })
        .catch((error) => {
          if (error.errorInfo.code == 'auth/id-token-expired') {
            this.accessDenied(req.url, res, undefined, error.errorInfo);
          } else {
            this.accessDenied(
              req.url,
              res,
              error.errorInfo.message,
              error.errorInfo,
            );
          }
        });
    } else {
      throw new ConflictException('Access Denied as Token does not exist');
    }
  }

  private accessDenied(
    url: string,
    res: Response,
    message: string,
    others?: any,
  ) {
    res.status(403).json({
      statusCode: 403,
      timestamp: new Date().toISOString(),
      path: url,
      message: message ? message : 'Access Denied',
      ...others,
    });
  }
}
Example #11
Source File: auth.middleware.ts    From life-helper-backend with MIT License 5 votes vote down vote up
/**
 * 鉴权中间件
 *
 *
 * ### 说明
 *
 * ```markdown
 * 1. 鉴权信息会放在请求头的 `Authorization` 字段。
 * 2. 鉴权信息格式 `TOKEN ${token}` 或 `CODE ${code}`。
 * ```
 */
@Injectable()
export class AuthMiddleware implements NestMiddleware {
  private readonly logger = new Logger(AuthMiddleware.name)

  constructor(private readonly tokenService: TokenService, private readonly userService: UserService) {}

  async use(request: ExtRequest, response: Response, next: NextFunction): Promise<void> {
    const user: RequestUser = request.user || { id: 0, authType: 'none' }

    const authValue = request.get('authorization')

    if (authValue) {
      const [type, value] = authValue.split(' ')
      if (type && type.toUpperCase() === 'TOKEN') {
        user.id = await this.tokenService.getUserIdByToken(value)
        user.authType = 'token'
      } else if (type && type.toUpperCase() === 'CODE') {
        user.id = await this.userService.getUserIdByCode(value)
        user.authType = 'code'
      } else {
        this.logger.debug(`错误的鉴权信息格式,authorization => ${authValue}`)
      }
    }

    // 挂载 `user` 对象
    request.user = user

    next()
  }
}
Example #12
Source File: context.middleware.ts    From ironfish-api with Mozilla Public License 2.0 5 votes vote down vote up
@Injectable()
export class ContextMiddleware implements NestMiddleware {
  use(req: Request, _res: Response, next: NextFunction): void {
    req.context = {};
    next();
  }
}
Example #13
Source File: async-hooks.middleware.ts    From nest-xray with MIT License 5 votes vote down vote up
@Injectable()
export class AsyncHooksMiddleware implements NestMiddleware {
  constructor(private readonly asyncContext: AsyncContext) {}

  public use(req: any, res: any, next: () => void) {
    this.asyncContext.run(next);
  }
}
Example #14
Source File: dynamic.strategy.ts    From radiopanel with GNU General Public License v3.0 4 votes vote down vote up
@Injectable()
export class DynamicStrategyProvider implements NestMiddleware {
	constructor(
		private userService: UserService,
		private roleService: RoleService,
		private configService: ConfigService,
		private authMethodService: AuthMethodService,
	) {}

	public async use(req: Request, res: Response, next: NextFunction) {
		const authMethod = await this.authMethodService.findOne(req.params['0']);

		if (!authMethod) {
			return next();
		}

		const strategy = await this.getConfiguration(authMethod);

		passport.authenticate(strategy)(req, res, next);
	}

	private async getConfiguration(authMethod: AuthenticationMethod): Promise<SamlStrategy | OAuth2Strategy> {
		if (authMethod.type === 'saml') {
			return this.createSamlStrategy(authMethod);
		}

		if (authMethod.type === 'oauth2') {
			return this.createOAuthStrategy(authMethod);
		}

		if (authMethod.type === 'discord') {
			return this.createDiscordStrategy(authMethod);
		}
	}

	private async createSamlStrategy(authMethod: AuthenticationMethod): Promise<SamlStrategy> {
		return new SamlStrategy(
			{
				callbackUrl: `${this.configService.get('app.frontendBaseUrl')}/api/v1/auth/login/${authMethod.uuid}`,
				entryPoint: authMethod.config.entryPoint,
				cert: authMethod.config.cert,
				issuer: authMethod.config.issuer
			},
			async (user: SamlProfile, done: Function): Promise<any> => {
				const existingUser = await this.userService.findOne({ email: user.nameID, authenticationMethodUuid: authMethod.uuid });

				if (existingUser) {
					return done(null, existingUser);
				}

				const createdUser = await this.userService.create({
					uuid: uuid.v4(),
					password: bcryptjs.hashSync(this.generatePassword(50)),
					email: user.nameID,
					authenticationMethodUuid: authMethod.uuid,
					username: user['http://schemas.microsoft.com/identity/claims/displayname'] as string || user.nameID,
					updatedAt: new Date(),
					createdAt: new Date(),
					avatar: this.configService.get('app.frontendBaseUrl') + '/assets/img/logo-alternative.png',
				});

				await this.userService.assignRole(createdUser.uuid, authMethod.defaultRoleUuid);

				done(null, createdUser)
			}
		);
	}

	private async createOAuthStrategy(authMethod: AuthenticationMethod): Promise<OAuthStrategy> {
		return new OAuthStrategy(
			{
				authorizationURL: authMethod.config.authorizationURL,
				tokenURL: authMethod.config.tokenURL,
				clientID: authMethod.config.clientID,
				clientSecret: authMethod.config.clientSecret,
				callbackURL: `${this.configService.get('app.frontendBaseUrl')}/api/v1/auth/login/${authMethod.uuid}`,
				scope: authMethod.config.scope || 'openid profile email'
			},
			async (accessToken: string, _, __, done: Function): Promise<any> => {
				await got.get(authMethod.config.userinfoURL, {
					headers: {
						'Authorization': `Bearer ${accessToken}`
					},
					resolveBodyOnly: true,
					responseType: 'json'
				})
					.json<{
						sub: string;
						nickname: string;
						name: string;
						picture: string;
						updated_at: string;
						email: string;
						email_verified: false;
					}>()
					.then(async (result) => {
						const existingUser = await this.userService.findOne({ email: result.email, authenticationMethodUuid: authMethod.uuid });

						if (existingUser) {
							return done(null, existingUser);
						}

						const createdUser = await this.userService.create({
							uuid: uuid.v4(),
							password: bcryptjs.hashSync(this.generatePassword(50)),
							email: result.email,
							authenticationMethodUuid: authMethod.uuid,
							username: result.nickname,
							updatedAt: new Date(),
							createdAt: new Date(),
							avatar: result.picture,
						});

						await this.userService.assignRole(createdUser.uuid, authMethod.defaultRoleUuid);

						return done(null, createdUser)
					})
			}
		);
	}
	private async createDiscordStrategy(authMethod: AuthenticationMethod): Promise<OAuthStrategy> {
		const strategy = new OAuthStrategy(
			{
				authorizationURL: 'https://discord.com/api/oauth2/authorize',
				tokenURL: 'https://discord.com/api/oauth2/token',
				clientID: authMethod.config.clientID,
				clientSecret: authMethod.config.clientSecret,
				callbackURL: `${this.configService.get('app.frontendBaseUrl')}/api/v1/auth/login/${authMethod.uuid}`,
				scope: 'identify email guilds',
			},
			async (accessToken: string, _, __, done: Function): Promise<any> => {
				console.log(accessToken)
				await got.get('https://discord.com/api/users/@me', {
					headers: {
						'authorization': `Bearer ${accessToken}`
					},
					resolveBodyOnly: true,
					responseType: 'json'
				})
					.json<{
						id: string;
						username: string;
						avatar: string;
						email: string;
					}>()
					.then(async (result) => {
						const existingUser = await this.userService.findOne({ email: result.email, authenticationMethodUuid: authMethod.uuid });

						if (existingUser) {
							return done(null, existingUser);
						}

						const createdUser = await this.userService.create({
							uuid: uuid.v4(),
							password: bcryptjs.hashSync(this.generatePassword(50)),
							email: result.email,
							authenticationMethodUuid: authMethod.uuid,
							username: result.username,
							updatedAt: new Date(),
							createdAt: new Date(),
							avatar: `https://cdn.discordapp.com/avatars/${result.id}/${result.avatar}.png`,
						});

						await this.userService.assignRole(createdUser.uuid, authMethod.defaultRoleUuid);

						return done(null, createdUser)
					})
					.catch((e) => console.error(e.response.body))
			}
		);

		return strategy;
	}

	private generatePassword = (
		length = 20,
		wishlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$'
	  ): string =>
		Array.from(crypto.randomFillSync(new Uint32Array(length)))
		  .map((x) => wishlist[x % wishlist.length])
		  .join('')
}