File

src/auth/discord/discord.service.ts

Index

Properties
Methods

Constructor

constructor(usersService: UsersService, utilsService: UtilsService, authService: AuthService, configService: ConfigService, codesService: CodesService)
Parameters :
Name Type Optional
usersService UsersService No
utilsService UtilsService No
authService AuthService No
configService ConfigService No
codesService CodesService No

Methods

Public Async onAuth
onAuth(token: string)
Parameters :
Name Type Optional
token string No
Returns : unknown
Public resolvePfp
resolvePfp(userId: string, pfpId: string)
Parameters :
Name Type Optional
userId string No
pfpId string No
Returns : string
Public Async resolveUserByToken
resolveUserByToken(token: string, tokenType: string)
Parameters :
Name Type Optional
token string No
tokenType string No
Returns : Promise<DiscordUserResolvable | undefined>
Async validateToken
validateToken(token: string)
Parameters :
Name Type Optional
token string No
Returns : Promise<DiscordTokenRequestResult | void>

Properties

Private Readonly httpService
Type : HttpService
Default value : new HttpService()
Private Readonly logger
Default value : new Logger(DiscordService.name)
Private Readonly oauth
Default value : new OAuth()
import {
  Injectable,
  Inject,
  forwardRef,
  Logger,
  UnauthorizedException,
} from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import {
  DiscordUserResolvable,
  DiscordTokenRequestResult,
} from '../../../types';
import { UsersService } from '../../users/users.service';
import { UtilsService } from '../../utils/utils.service';
import { AuthService } from '../auth.service';
import { ConfigService } from '@nestjs/config';
import OAuth from 'discord-oauth2';
import { CodesService } from '../../codes/codes.service';

@Injectable()
export class DiscordService {
  private readonly logger = new Logger(DiscordService.name);
  private readonly oauth = new OAuth();
  private readonly httpService: HttpService = new HttpService();
  constructor(
    private readonly usersService: UsersService,
    private readonly utilsService: UtilsService,
    @Inject(forwardRef(() => AuthService))
    private readonly authService: AuthService,
    private readonly configService: ConfigService,
    private readonly codesService: CodesService,
  ) {}

  public async onAuth(token: string) {
    const resp = await this.validateToken(token);
    this.logger.debug('Discord resp', resp);
    if (!resp) {
      throw new UnauthorizedException();
    }
    const user = await this.resolveUserByToken(
      resp!.access_token,
      resp!.token_type,
    );
    this.logger.debug('Resolved user', user);
    const { valid } = await this.usersService.isSnowflakeValid(user.id);
    this.logger.debug(`Discord user validity: ${valid}`);
    if (valid) {
      return this.utilsService.createSignal('SET_AUTH_COOKIE', {
        cookie: this.authService.createJwt({ snowflake: user.id }),
      });
    } else {
      //TODO! redirect to dash
      const code = await this.codesService.createCode(
        'OAUTH_PASSWD',
        20,
        undefined,
        JSON.stringify([
          resp!.access_token,
          resp!.token_type,
          user.id,
          'discord',
        ]),
        false,
      );
      return [user?.id, code.code];
    }
  }

  public async resolveUserByToken(
    token: string,
    tokenType: string,
  ): Promise<DiscordUserResolvable | undefined> {
    try {
      const r = await this.httpService.get<DiscordUserResolvable>(
        `https://discord.com/api/users/@me`,
        {
          headers: {
            authorization: `${tokenType} ${token}`,
          },
        },
      );
      const p = await r.toPromise();
      return p.data;
    } catch (err) {
      return undefined;
    }
  }

  async validateToken(
    token: string,
  ): Promise<DiscordTokenRequestResult | void> {
    this.logger.log(
      `Attempting Discord oauth with code ${token}`,
      'Secret',
      this.configService.get('DISC_SEC'),
    );
    return await this.oauth
      .tokenRequest({
        clientId: this.configService.get('DISC_ID'),
        clientSecret: this.configService.get('DISC_SEC'),
        scope: ['identify', 'email'],
        grantType: 'authorization_code',
        code: token,
        redirectUri: encodeURI(
          `${
            this.configService.get('DISCORD_REDIR_URL') ||
            'http://localhost:5000'
          }/v3/auth/callback/discord`,
        ),
      })
      .catch((err) => {
        this.logger.error('Error happened during Discord oauth', err);
      });
  }

  public resolvePfp(userId: string, pfpId: string) {
    return `https://cdn.discordapp.com/avatars/${userId}/${pfpId}.${
      pfpId.startsWith('a_') ? 'gif' : 'png'
    }`;
  }
}

results matching ""

    No results matching ""