mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-21 22:42:12 +02:00
feat(auth): session management UI and improved account lockout feedback
Session management: - GET /auth/sessions and DELETE /auth/sessions/:id endpoints - listSessions() and revokeSession() in shared-auth client - SessionManager component: active sessions list with device info, "Aktuell" badge, revoke individual or all other sessions - Integrated in ManaCore settings page Account lockout UX: - Dedicated amber lockout banner (distinct from generic rate-limit) - "Konto vorübergehend gesperrt" with MM:SS countdown - "Passwort zurücksetzen" link as alternative action - formatCountdown helper for clean time display Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2624e5a6b7
commit
8f56feb115
8 changed files with 898 additions and 4 deletions
|
|
@ -824,6 +824,52 @@ export function createAuthService(config: AuthServiceConfig) {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* List active sessions
|
||||
*/
|
||||
async listSessions(): Promise<any[]> {
|
||||
try {
|
||||
const appToken = await service.getAppToken();
|
||||
if (!appToken) return [];
|
||||
|
||||
const res = await fetch(`${baseUrl}/api/v1/auth/sessions`, {
|
||||
headers: { Authorization: `Bearer ${appToken}` },
|
||||
});
|
||||
|
||||
if (!res.ok) return [];
|
||||
return await res.json();
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Revoke a session
|
||||
*/
|
||||
async revokeSession(sessionId: string): Promise<AuthResult> {
|
||||
try {
|
||||
const appToken = await service.getAppToken();
|
||||
if (!appToken) return { success: false, error: 'Not authenticated' };
|
||||
|
||||
const res = await fetch(`${baseUrl}/api/v1/auth/sessions/${sessionId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${appToken}` },
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({}));
|
||||
return { success: false, error: err.message || 'Failed to revoke session' };
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Failed to revoke session',
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the current app token
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue