auth.resolver.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { Args, Context, Mutation, Query, Resolver } from '@nestjs/graphql';
  2. import { Request, Response } from 'express';
  3. import { LoginMutationArgs, LoginResult, MutationResolvers, Permission } from 'shared/generated-types';
  4. import { ConfigService } from '../../config/config.service';
  5. import { User } from '../../entity/user/user.entity';
  6. import { AuthService } from '../../service/providers/auth.service';
  7. import { ChannelService } from '../../service/providers/channel.service';
  8. import { Allow } from '../common/auth-guard';
  9. import { extractAuthToken } from '../common/extract-auth-token';
  10. import { setAuthToken } from '../common/set-auth-token';
  11. @Resolver('Auth')
  12. export class AuthResolver {
  13. constructor(
  14. private authService: AuthService,
  15. private channelService: ChannelService,
  16. private configService: ConfigService,
  17. ) {}
  18. /**
  19. * Attempts a login given the username and password of a user. If successful, returns
  20. * the user data and returns the token either in a cookie or in the response body.
  21. */
  22. @Mutation()
  23. async login(
  24. @Args() args: LoginMutationArgs,
  25. @Context('req') req: Request,
  26. @Context('res') res: Response,
  27. ): Promise<LoginResult> {
  28. const session = await this.authService.authenticate(args.username, args.password);
  29. setAuthToken({
  30. req,
  31. res,
  32. authOptions: this.configService.authOptions,
  33. rememberMe: args.rememberMe || false,
  34. authToken: session.token,
  35. });
  36. return {
  37. user: this.publiclyAccessibleUser(session.user),
  38. };
  39. }
  40. @Mutation()
  41. async logout(@Context('req') req: Request, @Context('res') res: Response): Promise<boolean> {
  42. const token = extractAuthToken(req, this.configService.authOptions.tokenMethod);
  43. if (!token) {
  44. return false;
  45. }
  46. await this.authService.invalidateSessionByToken(token);
  47. setAuthToken({
  48. req,
  49. res,
  50. authOptions: this.configService.authOptions,
  51. rememberMe: false,
  52. authToken: '',
  53. });
  54. return true;
  55. }
  56. /**
  57. * Returns information about the current authenticated user.
  58. */
  59. @Query()
  60. @Allow(Permission.Authenticated)
  61. async me(@Context('req') request: Request & { user: User }) {
  62. const user = await this.authService.getUserById(request.user.id);
  63. return user ? this.publiclyAccessibleUser(user) : null;
  64. }
  65. /**
  66. * Exposes a subset of the User properties which we want to expose to the public API.
  67. */
  68. private publiclyAccessibleUser(user: User): any {
  69. return {
  70. id: user.id,
  71. identifier: user.identifier,
  72. channelTokens: this.getAvailableChannelTokens(user),
  73. };
  74. }
  75. private getAvailableChannelTokens(user: User): string[] {
  76. return user.roles.reduce((tokens, role) => role.channels.map(c => c.token), [] as string[]);
  77. }
  78. }