access-token.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import type { IUserHasId, Scope } from '@growi/core/dist/interfaces';
  2. import { serializeUserSecurely } from '@growi/core/dist/models/serializers';
  3. import type { Response } from 'express';
  4. import { AccessToken } from '~/server/models/access-token';
  5. import loggerFactory from '~/utils/logger';
  6. import type { AccessTokenParserReq } from './interfaces';
  7. const logger = loggerFactory('growi:middleware:access-token-parser:access-token');
  8. export const parserForAccessToken = (scopes: Scope[]) => {
  9. return async(req: AccessTokenParserReq, res: Response): Promise<void> => {
  10. const accessToken = req.query.access_token ?? req.body.access_token;
  11. if (accessToken == null || typeof accessToken !== 'string') {
  12. return;
  13. }
  14. if (scopes == null || scopes.length === 0) {
  15. logger.debug('scopes is empty');
  16. return;
  17. }
  18. // check the access token is valid
  19. const userId = await AccessToken.findUserIdByToken(accessToken, scopes);
  20. if (userId == null) {
  21. logger.debug('The access token is invalid');
  22. return;
  23. }
  24. // check the user is valid
  25. const { user: userByAccessToken }: {user: IUserHasId} = await userId.populate('user');
  26. if (userByAccessToken == null) {
  27. logger.debug('The access token\'s associated user is invalid');
  28. return;
  29. }
  30. if (userByAccessToken.readOnly) {
  31. logger.debug('The access token\'s associated user is read-only');
  32. return;
  33. }
  34. // transforming attributes
  35. req.user = serializeUserSecurely(userByAccessToken);
  36. if (req.user == null) {
  37. return;
  38. }
  39. logger.debug('Access token parsed.');
  40. return;
  41. };
  42. };