import { Controller, Get, Next, NotFoundException, Post, Req, Res, UseGuards, } from '@nestjs/common'; import { ApiBearerAuth, ApiExcludeEndpoint, ApiTags } from '@nestjs/swagger'; import { NextFunction, Request, Response } from 'express'; import { Scope } from 'src/decorators/scope.decorator'; import { CurrentUser } from 'src/decorators/user.decorator'; import { OAuth2Guard } from 'src/guards/oauth2.guard'; import { ConfigurationService } from 'src/modules/config/config.service'; import { User } from 'src/modules/objects/user/user.entity'; import { OAuth2Service } from '../../oauth2/oauth2.service'; @ApiTags('oauth2') @Controller('oauth2') export class OAuth2Controller { constructor( private _service: OAuth2Service, private _config: ConfigurationService, ) {} // These requests are just passed straight on to the provider controller @Get('authorize') public authorizeGetWrapper( @Req() req: Request, @Res() res: Response, @Next() next: NextFunction, ): void { return this._service.oauth.controller.authorization(req, res, next); } @ApiExcludeEndpoint() @Post('authorize') public authorizePostWrapper( @Req() req: Request, @Res() res: Response, @Next() next: NextFunction, ): void { return this._service.oauth.controller.authorization(req, res, next); } @Post('token') public tokenWrapper( @Req() req: Request, @Res() res: Response, @Next() next: NextFunction, ): void { return this._service.oauth.controller.token(req, res, next); } @ApiBearerAuth() @Post('introspect') public introspectWrapper( @Req() req: Request, @Res() res: Response, @Next() next: NextFunction, ): void { return this._service.oauth.controller.introspection(req, res, next); } // User information endpoint @ApiExcludeEndpoint() @Get('user') @UseGuards(OAuth2Guard) public async userInfo( @CurrentUser() user: User, @Scope() scope: string, ): Promise> { if (!user) { throw new NotFoundException('No such user'); } const userData: Record = { id: user.id, uuid: user.uuid, username: user.username, display_name: user.display_name, // Standard claims sub: user.uuid, name: user.display_name, preferred_username: user.username, nickname: user.display_name, }; if (scope.includes('email') || scope.includes('user:email')) { userData.email = user.email; userData.email_verified = true; } if ( (scope.includes('image') || scope.includes('picture') || scope.includes('user:image')) && user.picture ) { userData.image = `${this._config.get('app.base_url')}/uploads/${ user.picture.file }`; userData.image_file = user.picture.file; } if ( scope.includes('privileges') || (scope.includes('user:privileges') && user.privileges?.length) ) { userData.privileges = user.privileges.map(({ name }) => name); } return userData; } }