import { Inject, Injectable } from '@nestjs/common'; import { DeleteResult, Repository } from 'typeorm'; import { User } from '../user/user.entity'; import { OAuth2ClientAuthorization } from './oauth2-client-authorization.entity'; import { OAuth2ClientURL, OAuth2ClientURLType, } from './oauth2-client-url.entity'; import { OAuth2Client } from './oauth2-client.entity'; @Injectable() export class OAuth2ClientService { constructor( @Inject('CLIENT_REPOSITORY') private clientRepository: Repository, @Inject('CLIENT_URL_REPOSITORY') private clientUrlRepository: Repository, @Inject('CLIENT_AUTHORIZATION_REPOSITORY') private clientAuthRepository: Repository, ) {} public async hasAuthorized( userId: number, clientId: string, scope: string[], ): Promise { const authorization = await this.clientAuthRepository.findOne({ where: { user: { id: userId, }, client: { client_id: clientId, }, }, relations: ['user', 'client'], }); if (!authorization) { return false; } // Scopes must have been allowed const splitScope = authorization.scope.split(' '); if (scope.every((item) => splitScope.includes(item))) { return true; } return false; } public async createAuthorization( user: User, client: OAuth2Client, scope: string[], ): Promise { const existing = await this.clientAuthRepository.findOne({ where: { user, client, }, relations: ['user', 'client'], }); if (existing) { const splitScope = existing.scope.split(' '); scope.forEach((item) => { if (!splitScope.includes(item)) { splitScope.push(item); } }); existing.scope = splitScope.join(' '); await this.clientAuthRepository.save(existing); return existing; } const authorization = new OAuth2ClientAuthorization(); authorization.user = user; authorization.client = client; authorization.scope = scope.join(' '); await this.clientAuthRepository.insert(authorization); return authorization; } public async getAuthorizations( user: User, ): Promise { return this.clientAuthRepository.find({ relations: ['user', 'client', 'client.urls'], where: { user }, }); } public async revokeAuthorization( auth: OAuth2ClientAuthorization, ): Promise { console.log(auth); return this.clientAuthRepository.remove(auth); } public async getAuthorization( user: User, authId: number, ): Promise { return this.clientAuthRepository.findOne({ where: { user, id: authId, }, relations: ['user'], }); } public async getById(id: string | number): Promise { let client: OAuth2Client; if (typeof id === 'string') { client = await this.clientRepository.findOne( { client_id: id }, { relations: ['urls', 'picture'] }, ); } else { client = await this.clientRepository.findOne( { id }, { relations: ['urls', 'picture'] }, ); } return client; } public async getClientURLs( id: string, type?: OAuth2ClientURLType, ): Promise { return this.clientUrlRepository.find({ where: { client: { client_id: id }, type, }, relations: ['client'], }); } public async checkRedirectURI(id: string, url: string): Promise { return !!(await this.clientUrlRepository.findOne( { client: { client_id: id }, url, type: OAuth2ClientURLType.REDIRECT_URI, }, { relations: ['client'] }, )); } }