Repository: freeCodeCamp/freeCodeCamp
File: api/src/plugins/auth0.ts (TypeScript)

Code before:
        // have to update the test or write custom state create/verify
        // functions.
        if (error instanceof Error && error.message === 'Invalid state') {
          logger.error('Auth failed: invalid state');
        } else {
          logger.error('Auth failed:');
          logger.error(error);
          fastify.Sentry.captureException(error);
        }
        // It's important _not_ to redirect to /signin here, as that could
        // create an infinite loop.
        return reply.redirectWithMessage(returnTo, {
          type: 'danger',
          content: 'flash.generic-error'
        });
      }

      let email;
      try {
        const userinfo = (await fastify.auth0OAuth.userinfo(token)) as {
          email: string;
        };
        email = userinfo.email;
        if (typeof email !== 'string') throw Error('Invalid userinfo response');
      } catch (error) {
        logger.error('Auth failed', error);
        fastify.Sentry.captureException(error);
        return reply.redirect('/signin');
      }

      const { id, acceptedPrivacyTerms } = await findOrCreateUser(
        fastify,
        email
      );

      reply.setAccessTokenCookie(createAccessToken(id));

      if (acceptedPrivacyTerms) {
        void reply.redirectWithMessage(returnTo, {
          type: 'success',
          content: 'flash.signin-success'
        });
      } else {
        void reply.redirectWithMessage(`${redirectBase}/email-sign-up`, {
          type: 'success',
          content: 'flash.signin-success'
        });
      }
    });

    done();

Review comment (bug):
I realise this is unrelated to this PR, but this causes `error` to be ignored: https://github.com/pinojs/pino/blob/main/docs/api.md#interpolationvalues-any

```suggestion
        logger.error({ error }, 'Auth failed');
```

Code after:
        // have to update the test or write custom state create/verify
        // functions.
        if (error instanceof Error && error.message === 'Invalid state') {
          logger.error('Auth failed: invalid state');
        } else {
          logger.error('Auth failed:');
          logger.error(error);
          fastify.Sentry.captureException(error);
        }
        // It's important _not_ to redirect to /signin here, as that could
        // create an infinite loop.
        return reply.redirectWithMessage(returnTo, {
          type: 'danger',
          content: 'flash.generic-error'
        });
      }

      let email;
      try {
        const userinfo = (await fastify.auth0OAuth.userinfo(token)) as {
          email: string;
        };
        email = userinfo.email;
        if (typeof email !== 'string') throw Error('Invalid userinfo response');
      } catch (error) {
        logger.error({ error }, 'Auth failed');
        fastify.Sentry.captureException(error);
        return reply.redirect('/signin');
      }

      const { id, acceptedPrivacyTerms } = await findOrCreateUser(
        fastify,
        email
      );

      reply.setAccessTokenCookie(createAccessToken(id));

      if (acceptedPrivacyTerms) {
        void reply.redirectWithMessage(returnTo, {
          type: 'success',
          content: 'flash.signin-success'
        });
      } else {
        void reply.redirectWithMessage(`${redirectBase}/email-sign-up`, {
          type: 'success',
          content: 'flash.signin-success'
        });
      }
    });

    done();