-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
feat: Add a CORS-enabled endpoint for token refresh in Hydra plugin #4743
Conversation
f267127
to
d01e62f
Compare
@@ -68,6 +68,19 @@ WebApp.connectHandlers.use("/consent", (req, res) => { | |||
.catch((errorMessage) => errorHandler(errorMessage, res)); | |||
}); | |||
|
|||
WebApp.connectHandlers.use("/token/refresh", (req, res) => { | |||
res.setHeader("Access-Control-Allow-Origin", process.env.OAUTH2_CLIENT_DOMAIN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to this, you need the Vary: Origin
header, too: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin#CORS_and_caching
There would likely be many different domains hitting this. I believe the way this is usually done is setting the value to req.headers.origin
after verifying that that origin is allowed.
Maybe change ENV name to DOMAINS plural, split it to an array on commas, and then check whether the request origin header is in that array?
if (res.status < 200 || res.status > 302) { | ||
const json = await res.json(); | ||
Logger.error("An error occurred while calling refresh API", json.error_description); | ||
return Promise.reject(new Error(json.error_description)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an odd mix of normal promise and async/await. It seems like you could rewrite to be completely async/await:
async function refreshAuthToken({ refreshToken, clientId, clientSecret }) {
const res = await fetch(`${HYDRA_TOKEN_URL}`, {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
method: "POST",
body: `grant_type=refresh_token&refresh_token=${refreshToken}&response_type=token&client_id=${clientId}&client_secret=${clientSecret}`
});
const json = await res.json();
if (res.status < 200 || res.status > 302) {
Logger.error("An error occurred while calling refresh API", json.error_description);
throw new Error(json.error_description);
}
return json;
}
export default { | ||
getLoginRequest: (challenge) => get("login", challenge), | ||
acceptLoginRequest: (challenge, body) => put("login", "accept", challenge, body), | ||
rejectLoginRequest: (challenge) => put("login", "reject", challenge), | ||
getConsentRequest: (challenge) => get("consent", challenge), | ||
acceptConsentRequest: (challenge, body) => put("consent", "accept", challenge, body), | ||
rejectConsentRequest: (challenge, body) => put("consent", "reject", challenge, body), | ||
deleteUserSession: (id) => deleteUserSession(id) | ||
deleteUserSession: (id) => deleteUserSession(id), | ||
refreshAuthToken: (options) => refreshAuthToken(options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For these last two, they are not adding any arguments and are named the same, so you can eliminate a function layer by instead doing:
// ...
deleteUserSession,
refreshAuthToken
}
@aldeed thanks for the great feedback. I've addressed the comments here, but still yet to sort out the cookie issue on the other related PR. Decisions there may still require some changes here
@impactmass I went ahead and merged this into RC6 to keep things moving. If changes are necessary based on starter kit decisions, let's do a new PR for those. |
Part of reactioncommerce/example-storefront#350
Type: feature
Issue
To help enable refresh token in Starterkit (reactioncommerce/example-storefront#350)
Changes
Breaking changes
n/a
Testing