accounts icon indicating copy to clipboard operation
accounts copied to clipboard

Auth directive fails when excludeAddUserInContext is true

Open bmanturner opened this issue 3 years ago • 2 comments

I would like to use @auth without having to make a trip to the db on each request.

My expected behavior:

context.userId would be populated by jwtData and the @auth directive would work when excludeAddUserInContext: true

bmanturner avatar Aug 02 '21 13:08 bmanturner

Happy to merge a pr with the fix!

You might also want to use https://www.accountsjs.com/docs/server#stateless-session if you want to avoid other db calls on each request.

pradel avatar Aug 03 '21 14:08 pradel

I unfortunately do not have the time but maybe this can help someone else in the same spot in the future.

export const createAccountContext = async ({ req }: AccountsRequest): Promise<AccountsModuleContext> => {
  if (!req) {
    return {
      ip: '',
      userAgent: '',
      infos: {
        ip: '',
        userAgent: '',
      },
    };
  }

  const headerName = 'Authorization';
  let authToken = (req.headers[headerName] || req.headers[headerName.toLowerCase()]) as string;
  authToken = authToken && authToken.replace('Bearer ', '');

  let userId = '';
  if (authToken) {
    let sessionToken: string;
    try {
      const decodedAccessToken = jwt.verify(authToken, accountsServer.options.tokenSecret) as { data: JwtData };
      sessionToken = decodedAccessToken.data.token;
      userId = decodedAccessToken.data.userId;
    } catch (err) {
      throw new AccountsJsError('Auth token is not valid', ResumeSessionErrors.TokenVerificationFailed)
    }

    if (!accountsServer.options.useStatelessSession) {
      const session = await accountsMongo.findSessionByToken(sessionToken);
      if (!session) {
        throw new AccountsJsError('Session not found', ResumeSessionErrors.SessionNotFound);
      }
      if (!session.valid) {
        throw new AccountsJsError('Invalid Session', ResumeSessionErrors.InvalidSession);
      }
    }
  }

  const ip = getClientIp(req);
  let userAgent: string = (req.headers['user-agent'] as string) || '';
  if (req.headers['x-ucbrowser-ua']) {
    // special case of UC Browser
    userAgent = req.headers['x-ucbrowser-ua'] as string;
  }

  return {
    authToken,
    userAgent,
    userId,
    ip,
    infos: {
      userAgent,
      ip,
    },
  };
}

bmanturner avatar Aug 03 '21 21:08 bmanturner