File

src/auth/github/github.service.ts

Index

Properties
Methods

Constructor

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

Methods

Public Async fetchUser
fetchUser(code: string)
Parameters :
Name Type Optional
code string No
Returns : unknown
Public Async fetchUserMainEmail
fetchUserMainEmail(code: string)
Parameters :
Name Type Optional
code string No
Returns : unknown
Public Async onAuth
onAuth(code: string)
Parameters :
Name Type Optional
code string No
Returns : unknown
Private Async validateToken
validateToken(token: string)
Parameters :
Name Type Optional
token string No
Returns : unknown

Properties

Private Readonly logger
Default value : new Logger(GithubService.name)
import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { UsersService } from '../../users/users.service';
import { UtilsService } from '../../utils/utils.service';
import { AuthService } from '../auth.service';
import { ConfigService } from '@nestjs/config';
import { CodesService } from '../../codes/codes.service';
import querystring from 'querystring';
import {
  GithubEmails,
  GithubTokenRequestResult,
  PartialGithubUser,
} from '../../../types';
import { InvalidCodeException } from '../../exceptions/invalid-code.exception';

@Injectable()
export class GithubService {
  private readonly logger = new Logger(GithubService.name);
  constructor(
    private readonly httpService: HttpService,
    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(code: string) {
    const data = await this.validateToken(code);
    const user = await this.fetchUser(data.access_token);
    const { valid } = await this.usersService.isSnowflakeValid(
      user.id.toString(),
    ); //github ids are numbers
    if (valid) {
      return this.utilsService.createSignal('SET_AUTH_COOKIE', {
        cookie: this.authService.createJwt({ snowflake: user.id.toString() }),
      });
    } else {
      //TODO! redirect to dash
      const code = await this.codesService.createCode(
        'OAUTH_PASSWD',
        20,
        undefined,
        JSON.stringify([
          data!.access_token,
          data!.token_type,
          user.id.toString(),
          'github',
        ]),
        false,
      );
      return [user?.id.toString(), code.code];
    }
  }

  private async validateToken(token: string) {
    const query = querystring.stringify({
      client_id: this.configService.get('GH_ID'),
      client_secret: this.configService.get('GH_SEC'),
      code: token,
      redirect_uri: `${
        this.configService.get('DISCORD_REDIR_URL') || 'http://localhost:5000'
      }/v3/auth/callback/github`,
    });
    try {
      const resp = await this.httpService
        .post<GithubTokenRequestResult>(
          `https://github.com/login/oauth/access_token?${query}`,
          {},
          {
            headers: {
              Accept: 'application/json',
            },
          },
        )
        .toPromise();
      return resp.data;
    } catch (err) {
      throw new InvalidCodeException(true, false);
    }
  }

  public async fetchUser(code: string) {
    try {
      const r = await this.httpService
        .get<PartialGithubUser>('https://api.github.com/user', {
          headers: {
            Authorization: `token ${code}`,
          },
        })
        .toPromise();
      return r.data;
    } catch (err) {
      throw new InvalidCodeException(false, true);
    }
  }

  public async fetchUserMainEmail(code: string) {
    try {
      const r = await this.httpService
        .get<GithubEmails[]>('https://api.github.com/user/emails', {
          headers: {
            Authorization: `token ${code}`,
            Accept: 'application/json',
          },
        })
        .toPromise();
      const main = r.data.filter((email) => email.primary)[0];
      this.logger.debug('Default user email', main.email);
      return main.email;
    } catch (err) {
      throw new InvalidCodeException(false, true);
    }
  }
}

results matching ""

    No results matching ""