mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-19 05:55:34 +09:00
fix(api)!: enforce declared rate limits and correct route auth (#2500)
This commit is contained in:
1 parent
908e1b8bd4
commit
f8a04b8985
13 files changed
+317
-77
No files matched your search
@@ -181,21 +181,19 @@ export function AuthController(app: HonoApp) {
|
||||
app.post(
|
||||
'/auth/logout',
|
||||
RateLimitMiddleware(RateLimitConfigs.AUTH_LOGOUT),
|
||||
LoginRequiredAllowSuspicious,
|
||||
OpenAPI({
|
||||
operationId: 'logout_user',
|
||||
summary: 'Logout account',
|
||||
responseSchema: null,
|
||||
statusCode: 204,
|
||||
security: ['bearerToken', 'sessionToken'],
|
||||
security: ['botToken', 'bearerToken', 'sessionToken'],
|
||||
tags: ['Auth'],
|
||||
description:
|
||||
'Invalidate the current authentication token and end the session. The auth token in the Authorization header will no longer be valid.',
|
||||
'Invalidate the current authentication token and end the session. The auth token in the Authorization header will no longer be valid. A bot token has no session to end, so the call answers 204 and the token stays valid.',
|
||||
}),
|
||||
async (ctx) => {
|
||||
await ctx.get('authRequestService').logout({
|
||||
authorizationHeader: ctx.req.header('Authorization') ?? undefined,
|
||||
authToken: ctx.get('authToken') ?? undefined,
|
||||
});
|
||||
await ctx.get('authRequestService').logout({authToken: ctx.get('authToken')});
|
||||
return ctx.body(null, 204);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -84,7 +84,6 @@ interface AuthLoginMfaRequest {
|
||||
}
|
||||
|
||||
interface AuthLogoutRequest {
|
||||
authorizationHeader?: string;
|
||||
authToken?: string;
|
||||
}
|
||||
|
||||
@@ -187,10 +186,9 @@ export class AuthRequestService {
|
||||
return await this.toAuthTokenResponse(result);
|
||||
}
|
||||
|
||||
async logout({authorizationHeader, authToken}: AuthLogoutRequest): Promise<void> {
|
||||
const token = authToken ?? authorizationHeader;
|
||||
if (token) {
|
||||
await AuthSession.revokeToken(this.apiContext, token);
|
||||
async logout({authToken}: AuthLogoutRequest): Promise<void> {
|
||||
if (authToken) {
|
||||
await AuthSession.revokeToken(this.apiContext, authToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,18 @@ describe('Auth login and sessions', () => {
|
||||
await createBuilder(harness, account.token).post('/auth/logout').expect(204).execute();
|
||||
await createBuilder(harness, account.token).get('/users/@me').expect(401).execute();
|
||||
});
|
||||
it('logout requires a live session', async () => {
|
||||
await createBuilderWithoutAuth(harness).post('/auth/logout').expect(401).execute();
|
||||
await createBuilder(harness, createFakeAuthToken()).post('/auth/logout').expect(401).execute();
|
||||
const account = await createTestAccount(harness);
|
||||
await createBuilder(harness, account.token).post('/auth/logout').expect(204).execute();
|
||||
await createBuilder(harness, account.token).post('/auth/logout').expect(401).execute();
|
||||
});
|
||||
it('logout with a Bearer-prefixed session token revokes it', async () => {
|
||||
const account = await createTestAccount(harness);
|
||||
await createBuilder(harness, `Bearer ${account.token}`).post('/auth/logout').expect(204).execute();
|
||||
await createBuilder(harness, account.token).get('/users/@me').expect(401).execute();
|
||||
});
|
||||
it('treats /auth/sessions/logout as idempotent and removes targeted sessions', async () => {
|
||||
let account: TestAccount = await createTestAccount(harness);
|
||||
await createBuilder(harness, account.token)
|
||||
|
||||
Reference in new issue
Block a user