base-auth.resolver.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import {
  2. CurrentUser,
  3. CurrentUserChannel,
  4. LoginResult,
  5. MutationLoginArgs,
  6. } from '@vendure/common/lib/generated-types';
  7. import { unique } from '@vendure/common/lib/unique';
  8. import { Request, Response } from 'express';
  9. import { ForbiddenError, InternalServerError } from '../../../common/error/errors';
  10. import { ConfigService } from '../../../config/config.service';
  11. import { User } from '../../../entity/user/user.entity';
  12. import { getUserChannelsPermissions } from '../../../service/helpers/utils/get-user-channels-permissions';
  13. import { AuthService } from '../../../service/services/auth.service';
  14. import { UserService } from '../../../service/services/user.service';
  15. import { extractAuthToken } from '../../common/extract-auth-token';
  16. import { RequestContext } from '../../common/request-context';
  17. import { setAuthToken } from '../../common/set-auth-token';
  18. export class BaseAuthResolver {
  19. constructor(
  20. protected authService: AuthService,
  21. protected userService: UserService,
  22. protected configService: ConfigService,
  23. ) {}
  24. /**
  25. * Attempts a login given the username and password of a user. If successful, returns
  26. * the user data and returns the token either in a cookie or in the response body.
  27. */
  28. async login(
  29. args: MutationLoginArgs,
  30. ctx: RequestContext,
  31. req: Request,
  32. res: Response,
  33. ): Promise<LoginResult> {
  34. return await this.createAuthenticatedSession(ctx, args, req, res);
  35. }
  36. async logout(ctx: RequestContext, req: Request, res: Response): Promise<boolean> {
  37. const token = extractAuthToken(req, this.configService.authOptions.tokenMethod);
  38. if (!token) {
  39. return false;
  40. }
  41. await this.authService.deleteSessionByToken(ctx, token);
  42. setAuthToken({
  43. req,
  44. res,
  45. authOptions: this.configService.authOptions,
  46. rememberMe: false,
  47. authToken: '',
  48. });
  49. return true;
  50. }
  51. /**
  52. * Returns information about the current authenticated user.
  53. */
  54. async me(ctx: RequestContext) {
  55. const userId = ctx.activeUserId;
  56. if (!userId) {
  57. throw new ForbiddenError();
  58. }
  59. const user = userId && (await this.userService.getUserById(userId));
  60. return user ? this.publiclyAccessibleUser(user) : null;
  61. }
  62. /**
  63. * Creates an authenticated session and sets the session token.
  64. */
  65. protected async createAuthenticatedSession(
  66. ctx: RequestContext,
  67. args: MutationLoginArgs,
  68. req: Request,
  69. res: Response,
  70. ) {
  71. const session = await this.authService.authenticate(ctx, args.username, args.password);
  72. setAuthToken({
  73. req,
  74. res,
  75. authOptions: this.configService.authOptions,
  76. rememberMe: args.rememberMe || false,
  77. authToken: session.token,
  78. });
  79. return {
  80. user: this.publiclyAccessibleUser(session.user),
  81. };
  82. }
  83. /**
  84. * Updates the password of an existing User.
  85. */
  86. protected async updatePassword(
  87. ctx: RequestContext,
  88. currentPassword: string,
  89. newPassword: string,
  90. ): Promise<boolean> {
  91. const { activeUserId } = ctx;
  92. if (!activeUserId) {
  93. throw new InternalServerError(`error.no-active-user-id`);
  94. }
  95. return this.userService.updatePassword(activeUserId, currentPassword, newPassword);
  96. }
  97. /**
  98. * Exposes a subset of the User properties which we want to expose to the public API.
  99. */
  100. private publiclyAccessibleUser(user: User): CurrentUser {
  101. return {
  102. id: user.id as string,
  103. identifier: user.identifier,
  104. channels: getUserChannelsPermissions(user) as CurrentUserChannel[],
  105. };
  106. }
  107. }