import { OAuth2AccessToken } from '@icynet/oauth2-provider'; import { Controller, Get, Next, NotFoundException, Post, Req, Res, } from '@nestjs/common'; import { NextFunction, Request, Response } from 'express'; import { ConfigurationService } from 'src/modules/config/config.service'; import { OAuth2Service } from './oauth2.service'; @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); } @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); } @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 // TODO: Move to API @Get('user') public async userInfo( @Res({ passthrough: true }) res: Response, ): Promise> { const token = res.locals.accessToken as OAuth2AccessToken; const user = await this._service.userService.getById( token.user_id as number, ['picture', 'privileges'], ); 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 name: user.display_name, preferred_username: user.username, nickname: user.display_name, }; if (token.scope.includes('email') || token.scope.includes('user:email')) { userData.email = user.email; userData.email_verified = true; } if ( (token.scope.includes('image') || token.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 ( token.scope.includes('privileges') || (token.scope.includes('user:privileges') && user.privileges?.length) ) { userData.privileges = user.privileges; } return userData; } }