Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authorization Code redirect call in case of error #237

Open
simionrobert opened this issue Feb 3, 2020 · 2 comments
Open

Authorization Code redirect call in case of error #237

simionrobert opened this issue Feb 3, 2020 · 2 comments

Comments

@simionrobert
Copy link

Is there a mechanism to send to the redirect_uri some custom query parameters in case of error?
(I'm talking about https://localhost:8080/oauth2/authorize/decision endpoint)

Expected behavior

In case there is an error on

server.grant(oauth2orize.grant.code((client, redirectUri, user, ares, done) => {...});

it should call the redirect_uri with an error description as a query parameter.

Actual behavior

Instead, a json response containing the error description is returned.

{"error":"server_error","error_description":"The database service encountered an unexpected error."}
@jaredhanson
Copy link
Owner

What error handling middleware is being used on that endpoint?

@simionrobert
Copy link
Author

Thank you for responding.

The code I use is this. However, the error handler I wrote at the end is not called in case of error. I think the error handling is done internally, or I did not specify one?
Can you help me with a solution to this?

//////////////////////////////oauth2.js/////////////////////////
server.exchange(oauth2orize.exchange.code((client, code, redirectUri, done) => {

  // This code can either be for service/credential authorization. It should be found by value
  Code.findOne({ value: code, client_id: client._id }, function (err, authCode) {
    if (err) { return done(err); }
    if (authCode === undefined || authCode === null) { return done(errors.internalServerError); }
    if (client._id.toString() !== authCode.client_id) { return done(errors.invalidClientId); }
    if (redirectUri !== authCode.redirect_uri) { return done(errors.notMatchRedirectUri); }

    // check token availability
    if (authCode.creation_date.getTime() + 1000 * config.settings.code_expiring_time < Date.now()) { return done(errors.invalidCode, false); }

    switch (authCode.scope) {
      case 'service':
        crypto.randomBytes(256, function (err, buffer) {
          if (err) return done(errors.internalServerError);

          const tokenValue = buffer.toString('hex');

          Token.updateOne({ client_id: authCode.client_id, type: 'access_token' }, {
            value: tokenValue,
            type: 'access_token',
            user_id: authCode.user_id,
            client_id: authCode.client_id
          }, { upsert: true }, (err) => {
            if (err) return done(errors.databaseError);

            done(null, tokenValue, { token_type: "Bearer", expiresIn: config.settings.csc.access_token_expiring_time });
          });
        });
        break;

      case 'credential':
        //generate SAD. It gets deleted when the signature is done
        crypto.randomBytes(128, function (err, buffer) {
          if (err) return done(errors.internalServerError);

          const sadValue = buffer.toString('hex');
          const sad = new Sad({
            value: sadValue,
            hashes: authCode.hashes,
            credential_id: authCode.credential_id
          });

          sad.save((err) => {
            if (err) return done(errors.databaseError);

            // send response
            done(null, sadValue, { token_type: "SAD", expiresIn: config.settings.csc.sad_expiring_time });
          });
        });
        break;
      default:
        done(errors.internalServerError);
    }
  });
}));

module.exports.decision = [
  login.ensureLoggedIn(),
  server.decision(function (req, done) {
    return done(null, {
      scope: req.oauth2.req.scope,
      credentialID: req.body.credentialID,
      hash: req.body.hash,
      numSignatures: +req.body.num_signatures
    }) // this is ares
  }) // invokes server.grant()
];

//////////////////app.js////////////////////
app.post(`/oauth2/authorize/decision`, require('./routes/oauth2').decision);


// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  req.app.get('env') === 'development' ? logger.info(err) : {};

  // render the error page
  if (err.status !== undefined) {
    res.status(err.status);
    return res.json({
      error: err.message,
      error_description: err.description
    });
  }

  // fallback for unknown application errors
  res.status(errors.internalServerError.status);
  res.json({
    error: errors.internalServerError.message,
    error_description: errors.internalServerError.description
  });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants