v3 : une session dure jusqu'à ce qu'on la ferme, l'administration ferme celles d'une identité

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-10-23 08:45:26 +02:00
co-authored by Claude Opus 5.5
parent 422b45ab75
commit cf634c25d2
11 changed files with 163 additions and 13 deletions
+3
View File
@@ -304,6 +304,9 @@ export const en: Messages = {
'access.admin.take': 'Remove role',
'access.relink': 'New sign-in link',
'access.relink.link': 'Sign-in link for {name}, single use, valid for 14 days — to open their session on another device. It will not be shown again: copy it now.',
'access.sessions.close': 'Close their sessions ({n})',
'access.sessions.closeMine': 'Close my other sessions ({n})',
'access.sessions.closed': 'Sessions closed: {n}.',
'access.kind.g1': 'Ğ1',
'access.kind.invite': 'invitation',
'access.kind.dev': 'dev',
+3
View File
@@ -304,6 +304,9 @@ export const es: Messages = {
'access.admin.take': 'Retirar el rol',
'access.relink': 'Nuevo enlace de conexión',
'access.relink.link': 'Enlace de conexión para {name}, de un solo uso, válido 14 días — para abrir su sesión en otro dispositivo. No se volverá a mostrar: cópialo ahora.',
'access.sessions.close': 'Cerrar sus sesiones ({n})',
'access.sessions.closeMine': 'Cerrar mis otras sesiones ({n})',
'access.sessions.closed': 'Sesiones cerradas: {n}.',
'access.kind.g1': 'Ğ1',
'access.kind.invite': 'invitación',
'access.kind.dev': 'dev',
+3
View File
@@ -307,6 +307,9 @@ export const fr = {
'access.admin.take': 'Retirer le rôle',
'access.relink': 'Nouveau lien de connexion',
'access.relink.link': "Lien de connexion pour {name}, à usage unique, valable 14 jours — pour ouvrir sa session sur un autre appareil. Il ne s'affichera plus : copie-le maintenant.",
'access.sessions.close': 'Fermer ses sessions ({n})',
'access.sessions.closeMine': 'Fermer mes autres sessions ({n})',
'access.sessions.closed': 'Sessions fermées : {n}.',
'access.kind.g1': 'Ğ1',
'access.kind.invite': 'invitation',
'access.kind.dev': 'dev',
+10 -1
View File
@@ -16,7 +16,7 @@
status?: { pending: number; lastError: string | null; lastPublishedAt: string | null; lastCommit: string | null };
};
groups: { slug: string; name: string; policy: string; hidden: boolean; members: { identityId: string; grantedAt: string }[] }[];
identities: { id: string; kind: 'g1' | 'invite' | 'dev'; displayName: string; g1Member: boolean; admin: boolean; lastSeenAt: string | null; teamLink: string | null }[];
identities: { id: string; kind: 'g1' | 'invite' | 'dev'; displayName: string; g1Member: boolean; admin: boolean; lastSeenAt: string | null; teamLink: string | null; sessions: number }[];
invitations: { id: string; label: string; admin: boolean; groups: string[]; expiresAt: string }[];
teamLinks: TeamLink[];
}
@@ -77,6 +77,14 @@
});
}
// A lost device, a person who left: their sessions close (never the one in use here).
async function closeSessions(id: string) {
await act(async () => {
const r = await api.del<{ closed: number }>(`/access/identities/${encodeURIComponent(id)}/sessions`);
toasts.show(t('access.sessions.closed', { n: r.closed }));
});
}
async function status(id: number, s: 'seen' | 'done') {
await api.post(`/access/feedback/${id}`, { status: s });
await fb.load();
@@ -165,6 +173,7 @@
</span>
<span class="row">
{#if i.kind === 'invite'}<button class="btn quiet small" type="button" onclick={() => relink(i.id, i.displayName)}>{t('access.relink')}</button>{/if}
{#if i.sessions > 0}<button class="btn quiet small" type="button" onclick={() => closeSessions(i.id)}>{t(i.id === session.me?.id ? 'access.sessions.closeMine' : 'access.sessions.close', { n: i.sessions })}</button>{/if}
<button class="btn quiet small" type="button" onclick={() => act(() => api.post(`/access/identities/${encodeURIComponent(i.id)}/admin`, { admin: !i.admin }))}>{i.admin ? t('access.admin.take') : t('access.admin.give')}</button>
</span>
</li>