-
Notifications
You must be signed in to change notification settings - Fork 17
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
Keycloak test #612
base: master
Are you sure you want to change the base?
Keycloak test #612
Conversation
This is just an experiment connecting unchained with a self-hosted Keycloak server. |
fastify.get('/callback', async function (request, reply) { | ||
const accessToken = await this.keycloak.getAccessTokenFromAuthorizationCodeFlow(request); | ||
try { | ||
const userinfo = await this.keycloak.userinfo(accessToken.token.access_token); | ||
const { sub, email, resource_access, email_verified, name, given_name, family_name } = userinfo; | ||
const roles = resource_access?.['unchained-local']?.roles || []; | ||
const user = await engine.unchainedAPI.modules.users.findUserByUsername(`keycloak:${sub}`); | ||
|
||
if (user) { | ||
if (JSON.stringify(user.roles) !== JSON.stringify(roles)) { | ||
await engine.unchainedAPI.modules.users.updateRoles(user._id, roles); | ||
} | ||
request.unchainedContext.login(user); | ||
return reply.redirect('/'); | ||
} | ||
// TODO: try to use the preferred_username as the username first | ||
const newUserId = await engine.unchainedAPI.modules.users.createUser( | ||
{ | ||
username: `keycloak:${sub}`, | ||
password: null, | ||
email: email_verified ? email : undefined, | ||
profile: { | ||
displayName: name, | ||
address: { | ||
firstName: given_name, | ||
lastName: family_name, | ||
}, | ||
}, | ||
roles, | ||
}, | ||
{ skipMessaging: true, skipPasswordEnrollment: true }, | ||
); | ||
const newUser = await engine.unchainedAPI.modules.users.findUserById(newUserId); | ||
request.unchainedContext.login(newUser); | ||
return reply.redirect('/'); | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
|
||
// if later need to refresh the token this can be used | ||
// const { token: newToken } = await this.getNewAccessTokenUsingRefreshToken(token) | ||
|
||
return reply.send({ access_token: token.access_token }); | ||
}); |
Check failure
Code scanning / CodeQL
Missing rate limiting High
authorization
This route handler performs
authorization
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 1 month ago
To fix the problem, we need to introduce rate limiting to the Fastify application. We can use the @fastify/rate-limit
plugin to achieve this. This plugin allows us to set a maximum number of requests per time window for each IP address, which will help mitigate the risk of denial-of-service attacks.
We will:
- Install the
@fastify/rate-limit
package. - Register the rate limiting plugin with the Fastify instance.
- Configure the rate limiting settings to a reasonable default, such as 100 requests per 15 minutes.
-
Copy modified line R9 -
Copy modified lines R27-R31
@@ -8,2 +8,3 @@ | ||
import FastifyOAuth2 from '@fastify/oauth2'; | ||
import FastifyRateLimit from '@fastify/rate-limit'; | ||
|
||
@@ -25,2 +26,7 @@ | ||
}); | ||
|
||
await fastify.register(FastifyRateLimit, { | ||
max: 100, // maximum 100 requests per 15 minutes | ||
timeWindow: '15 minutes' | ||
}); | ||
|
-
Copy modified lines R42-R43
@@ -41,3 +41,4 @@ | ||
"@unchainedshop/plugins": "^3.0.0-alpha4", | ||
"fastify": "^5.1.0" | ||
"fastify": "^5.1.0", | ||
"@fastify/rate-limit": "^10.2.1" | ||
}, |
Package | Version | Security advisories |
@fastify/rate-limit (npm) | 10.2.1 | None |
No description provided.