import { OAuth2AdapterModel, OAuth2Provider } from '@icynet/oauth2-provider'; import { Injectable } from '@nestjs/common'; import { ConfigurationService } from 'src/modules/config/config.service'; import { OAuth2ClientService } from 'src/modules/objects/oauth2-client/oauth2-client.service'; import { OAuth2TokenService } from 'src/modules/objects/oauth2-token/oauth2-token.service'; import { UserService } from 'src/modules/objects/user/user.service'; import { TokenService } from 'src/modules/utility/services/token.service'; import { JWTService } from '../jwt/jwt.service'; import { AccessTokenAdapter } from './adapter/access-token.adapter'; import { ClientAdapter } from './adapter/client.adapter'; import { CodeAdapter } from './adapter/code.adapter'; import { IcyJWTAdapter } from './adapter/jwt.adapter'; import { RefreshTokenAdapter } from './adapter/refresh-token.adapter'; import { UserAdapter } from './adapter/user.adapter'; const SCOPE_DESCRIPTION: Record = { email: 'Email address', picture: 'Profile picture', }; const ALWAYS_AVAILABLE = ['Username and display name']; const ALWAYS_UNAVAILABLE = ['Password and other account settings']; @Injectable() export class OAuth2Service { private _oauthAdapter: OAuth2AdapterModel = { accessToken: new AccessTokenAdapter(this), refreshToken: new RefreshTokenAdapter(this), user: new UserAdapter(this), client: new ClientAdapter(this), code: new CodeAdapter(this), jwt: new IcyJWTAdapter(this), }; public oauth = new OAuth2Provider( this._oauthAdapter, async (req, res, client, scope) => { const fullClient = await this.clientService.getById(client.id as string); let allowedScopes = [...ALWAYS_AVAILABLE]; let disallowedScopes = [...ALWAYS_UNAVAILABLE]; Object.keys(SCOPE_DESCRIPTION).forEach((item) => { if (scope.includes(item)) { allowedScopes.push(SCOPE_DESCRIPTION[item]); } else { disallowedScopes.push(SCOPE_DESCRIPTION[item]); } }); if (scope.includes('management')) { allowedScopes = [ 'Manage Icy Network on your behalf', 'Commit administrative actions to the extent of your user privileges', ]; disallowedScopes = null; } res.render('authorize', { csrf: req.csrfToken(), user: req.user, client: fullClient, allowedScopes, disallowedScopes, }); }, ); constructor( public token: TokenService, public jwt: JWTService, public config: ConfigurationService, public userService: UserService, public clientService: OAuth2ClientService, public tokenService: OAuth2TokenService, ) { // if (process.env.NODE_ENV === 'development') { // this.oauth.logger.setLogLevel('debug'); // } } public splitScope(scope: string | string[]): string[] { if (!scope) { return []; } if (Array.isArray(scope)) { return scope; } return scope.includes(',') ? scope.split(',').map((item) => item.trim()) : scope.split(' '); } }