diff --git a/frontend/src/routes/admin/+page.svelte b/frontend/src/routes/admin/+page.svelte
index 5c0f481c..bc58d719 100644
--- a/frontend/src/routes/admin/+page.svelte
+++ b/frontend/src/routes/admin/+page.svelte
@@ -2222,6 +2222,24 @@
{#if u.role === 'admin'}{/if}
{u.role}
+ {#if u.is_external}
+
+
+
+ {t('admin.external_user', 'external')}
+
+ {/if}
{#if isOidcUser(u)}
@@ -3453,6 +3471,17 @@
text-transform: uppercase;
}
+ /* External / grant-only account marker. Sibling of `.badge--user`
+ in the same cell so the two stack horizontally; the accent
+ colour reuses `--color-warning-*` because "external" is the
+ same "attention needed" family as "you". */
+ .badge--external {
+ margin-left: var(--space-1);
+ background: var(--color-warning-bg);
+ color: var(--color-warning-text);
+ text-transform: uppercase;
+ }
+
/* Enabled/disabled feature flag indicator on the dashboard cards. */
.ds-flag {
font-size: 1.125rem;
diff --git a/frontend/static/locales/ar.json b/frontend/static/locales/ar.json
index 6a14bcb3..ee84fb3d 100644
--- a/frontend/static/locales/ar.json
+++ b/frontend/static/locales/ar.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "اسم قرص مطلوب.",
"drive_error_owner_required": "اختر مستخدمًا أو مجموعة كمالك للقرص.",
"create_drive": "إنشاء قرص مشترك",
- "no_drives": "لا توجد أقراص بعد."
+ "no_drives": "لا توجد أقراص بعد.",
+ "external_user": "خارجي",
+ "external_user_hint": "حساب بالدعوة فقط (magic-link أو OCM). لا يمكن أن يكون مسؤولًا ولا يمتلك حصة تخزين."
},
"profile": {
"page_title": "الملف الشخصي",
diff --git a/frontend/static/locales/de.json b/frontend/static/locales/de.json
index b0ea9910..f3883823 100644
--- a/frontend/static/locales/de.json
+++ b/frontend/static/locales/de.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "Laufwerk-Name ist erforderlich.",
"drive_error_owner_required": "Wähle einen Benutzer oder eine Gruppe als Eigentümer des Laufwerks.",
"create_drive": "Gemeinsames Laufwerk erstellen",
- "no_drives": "Noch keine Laufwerke."
+ "no_drives": "Noch keine Laufwerke.",
+ "external_user": "extern",
+ "external_user_hint": "Nur-Einladung-Konto (Magic-Link oder OCM). Kann kein Administrator sein und hat keinen Speicherumfang."
},
"profile": {
"page_title": "Profil",
diff --git a/frontend/static/locales/en.json b/frontend/static/locales/en.json
index 162fd5db..e8abeb3c 100644
--- a/frontend/static/locales/en.json
+++ b/frontend/static/locales/en.json
@@ -1166,7 +1166,9 @@
"drive_error_name_required": "Drive name is required.",
"drive_error_owner_required": "Pick a user or group as the drive owner.",
"create_drive": "Create shared drive",
- "no_drives": "No drives yet."
+ "no_drives": "No drives yet.",
+ "external_user": "external",
+ "external_user_hint": "Grant-only account (magic-link or OCM). Cannot be admin and has no storage envelope."
},
"profile": {
"page_title": "Profile",
diff --git a/frontend/static/locales/es.json b/frontend/static/locales/es.json
index b1632054..9c3a1015 100644
--- a/frontend/static/locales/es.json
+++ b/frontend/static/locales/es.json
@@ -884,7 +884,9 @@
"drive_error_name_required": "El nombre de la unidad es obligatorio.",
"drive_error_owner_required": "Elige un usuario o un grupo como propietario de la unidad.",
"create_drive": "Crear unidad compartida",
- "no_drives": "Aún no hay unidades."
+ "no_drives": "Aún no hay unidades.",
+ "external_user": "externo",
+ "external_user_hint": "Cuenta solo con invitación (magic-link u OCM). No puede ser admin y no tiene cuota de almacenamiento."
},
"profile": {
"page_title": "Perfil",
diff --git a/frontend/static/locales/fa.json b/frontend/static/locales/fa.json
index e1a630ad..8f3fb0b9 100644
--- a/frontend/static/locales/fa.json
+++ b/frontend/static/locales/fa.json
@@ -852,7 +852,9 @@
"drive_error_name_required": "نام دیسک الزامی است.",
"drive_error_owner_required": "یک کاربر یا گروه به عنوان مالک دیسک انتخاب کنید.",
"create_drive": "ایجاد دیسک اشتراکی",
- "no_drives": "هنوز دیسکی وجود ندارد."
+ "no_drives": "هنوز دیسکی وجود ندارد.",
+ "external_user": "خارجی",
+ "external_user_hint": "حساب فقط با دعوت (magic-link یا OCM). نمیتواند مدیر باشد و سهمیه ذخیرهسازی ندارد."
},
"profile": {
"page_title": "پروفایل",
diff --git a/frontend/static/locales/fr.json b/frontend/static/locales/fr.json
index 5fb1ada0..73e1dee0 100644
--- a/frontend/static/locales/fr.json
+++ b/frontend/static/locales/fr.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "Le nom du disque est requis.",
"drive_error_owner_required": "Choisissez un utilisateur ou un groupe comme propriétaire du disque.",
"create_drive": "Créer un disque partagé",
- "no_drives": "Aucun disque pour le moment."
+ "no_drives": "Aucun disque pour le moment.",
+ "external_user": "externe",
+ "external_user_hint": "Compte à accès par invitation (magic-link ou OCM). Ne peut pas être admin et n’a pas de quota de stockage."
},
"profile": {
"page_title": "Profil",
diff --git a/frontend/static/locales/hi.json b/frontend/static/locales/hi.json
index e09542d8..98c09042 100644
--- a/frontend/static/locales/hi.json
+++ b/frontend/static/locales/hi.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "ड्राइव का नाम आवश्यक है।",
"drive_error_owner_required": "ड्राइव के स्वामी के रूप में एक उपयोगकर्ता या समूह चुनें।",
"create_drive": "साझा ड्राइव बनाएँ",
- "no_drives": "अभी तक कोई ड्राइव नहीं।"
+ "no_drives": "अभी तक कोई ड्राइव नहीं।",
+ "external_user": "बाहरी",
+ "external_user_hint": "केवल-आमंत्रण खाता (magic-link या OCM). व्यवस्थापक नहीं हो सकता और कोई भंडारण कोटा नहीं है।"
},
"profile": {
"page_title": "प्रोफ़ाइल",
diff --git a/frontend/static/locales/it.json b/frontend/static/locales/it.json
index ea5c3c80..3f172444 100644
--- a/frontend/static/locales/it.json
+++ b/frontend/static/locales/it.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "Il nome dell'unità è obbligatorio.",
"drive_error_owner_required": "Scegli un utente o un gruppo come proprietario dell'unità.",
"create_drive": "Crea unità condivisa",
- "no_drives": "Ancora nessuna unità."
+ "no_drives": "Ancora nessuna unità.",
+ "external_user": "esterno",
+ "external_user_hint": "Account solo su invito (magic-link o OCM). Non può essere amministratore e non ha un limite di archiviazione."
},
"profile": {
"page_title": "Profilo",
diff --git a/frontend/static/locales/ja.json b/frontend/static/locales/ja.json
index ea7516df..5b645539 100644
--- a/frontend/static/locales/ja.json
+++ b/frontend/static/locales/ja.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "ドライブ名は必須です。",
"drive_error_owner_required": "ドライブの所有者としてユーザーまたはグループを選択してください。",
"create_drive": "共有ドライブを作成",
- "no_drives": "ドライブはまだありません。"
+ "no_drives": "ドライブはまだありません。",
+ "external_user": "外部",
+ "external_user_hint": "招待専用アカウント(マジックリンクまたは OCM)。管理者にはなれず、ストレージ枠を持ちません。"
},
"profile": {
"page_title": "プロフィール",
diff --git a/frontend/static/locales/ko.json b/frontend/static/locales/ko.json
index 2cf9728f..3cc691a8 100644
--- a/frontend/static/locales/ko.json
+++ b/frontend/static/locales/ko.json
@@ -1129,7 +1129,9 @@
"drive_error_name_required": "드라이브 이름은 필수입니다.",
"drive_error_owner_required": "드라이브 소유자로 사용자 또는 그룹을 선택하세요.",
"create_drive": "공유 드라이브 만들기",
- "no_drives": "아직 드라이브가 없습니다."
+ "no_drives": "아직 드라이브가 없습니다.",
+ "external_user": "외부",
+ "external_user_hint": "초대 전용 계정(매직 링크 또는 OCM). 관리자가 될 수 없으며 저장소 할당량이 없습니다."
},
"profile": {
"page_title": "프로필",
diff --git a/frontend/static/locales/nl.json b/frontend/static/locales/nl.json
index cc2de7c4..d5e1a463 100644
--- a/frontend/static/locales/nl.json
+++ b/frontend/static/locales/nl.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "Schijfnaam is vereist.",
"drive_error_owner_required": "Kies een gebruiker of groep als eigenaar van de schijf.",
"create_drive": "Gedeelde schijf aanmaken",
- "no_drives": "Nog geen schijven."
+ "no_drives": "Nog geen schijven.",
+ "external_user": "extern",
+ "external_user_hint": "Alleen-uitnodiging account (magic-link of OCM). Kan geen beheerder zijn en heeft geen opslagenveloppe."
},
"profile": {
"page_title": "Profiel",
diff --git a/frontend/static/locales/pl.json b/frontend/static/locales/pl.json
index f0cf4ce5..836194ec 100644
--- a/frontend/static/locales/pl.json
+++ b/frontend/static/locales/pl.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "Nazwa dysku jest wymagana.",
"drive_error_owner_required": "Wybierz użytkownika lub grupę jako właściciela dysku.",
"create_drive": "Utwórz dysk współdzielony",
- "no_drives": "Brak dysków."
+ "no_drives": "Brak dysków.",
+ "external_user": "zewnętrzny",
+ "external_user_hint": "Konto tylko z zaproszenia (magic-link lub OCM). Nie może być administratorem i nie ma limitu przestrzeni."
},
"profile": {
"page_title": "Profil",
diff --git a/frontend/static/locales/pt.json b/frontend/static/locales/pt.json
index 0601d0bb..9f7dfb8d 100644
--- a/frontend/static/locales/pt.json
+++ b/frontend/static/locales/pt.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "O nome da unidade é obrigatório.",
"drive_error_owner_required": "Escolha um utilizador ou grupo como proprietário da unidade.",
"create_drive": "Criar unidade partilhada",
- "no_drives": "Ainda não existem unidades."
+ "no_drives": "Ainda não existem unidades.",
+ "external_user": "externo",
+ "external_user_hint": "Conta apenas por convite (magic-link ou OCM). Não pode ser administrador e não tem quota de armazenamento."
},
"profile": {
"page_title": "Perfil",
diff --git a/frontend/static/locales/ru.json b/frontend/static/locales/ru.json
index 261130c7..e63bbbf0 100644
--- a/frontend/static/locales/ru.json
+++ b/frontend/static/locales/ru.json
@@ -869,7 +869,9 @@
"drive_error_name_required": "Имя диска обязательно.",
"drive_error_owner_required": "Выберите пользователя или группу как владельца диска.",
"create_drive": "Создать общий диск",
- "no_drives": "Пока нет дисков."
+ "no_drives": "Пока нет дисков.",
+ "external_user": "внешний",
+ "external_user_hint": "Аккаунт только по приглашению (magic-link или OCM). Не может быть администратором и не имеет квоты хранилища."
},
"profile": {
"page_title": "Профиль",
diff --git a/frontend/static/locales/zh-TW.json b/frontend/static/locales/zh-TW.json
index 2293c7c0..7b1354b5 100644
--- a/frontend/static/locales/zh-TW.json
+++ b/frontend/static/locales/zh-TW.json
@@ -852,7 +852,9 @@
"drive_error_name_required": "雲端硬碟名稱為必填。",
"drive_error_owner_required": "請選擇一位使用者或群組作為雲端硬碟擁有者。",
"create_drive": "建立共用雲端硬碟",
- "no_drives": "尚無雲端硬碟。"
+ "no_drives": "尚無雲端硬碟。",
+ "external_user": "外部",
+ "external_user_hint": "僅邀請帳戶(magic-link 或 OCM)。無法作為管理員,亦無儲存配額。"
},
"profile": {
"page_title": "個人資料",
diff --git a/frontend/static/locales/zh.json b/frontend/static/locales/zh.json
index 9e83032c..bcf7a13b 100644
--- a/frontend/static/locales/zh.json
+++ b/frontend/static/locales/zh.json
@@ -852,7 +852,9 @@
"drive_error_name_required": "云盘名称为必填项。",
"drive_error_owner_required": "请选择用户或群组作为云盘所有者。",
"create_drive": "创建共享云盘",
- "no_drives": "暂无云盘。"
+ "no_drives": "暂无云盘。",
+ "external_user": "外部",
+ "external_user_hint": "仅邀请账户(magic-link 或 OCM)。不能作为管理员,也没有存储配额。"
},
"profile": {
"page_title": "个人资料",
diff --git a/src/interfaces/api/handlers/admin_handler.rs b/src/interfaces/api/handlers/admin_handler.rs
index c6ac3ebb..5e3bdfb2 100644
--- a/src/interfaces/api/handlers/admin_handler.rs
+++ b/src/interfaces/api/handlers/admin_handler.rs
@@ -754,9 +754,14 @@ pub async fn list_users(
let limit = query.limit.unwrap_or(100).min(500);
let offset = query.offset.unwrap_or(0);
+ // Admin surface must show *every* account for audit — grant-only
+ // magic-link / OCM recipients (is_external = true) included. The
+ // internal-only variant is used by system address book / sharee
+ // search, where surfacing externals would leak identities. See
+ // `auth_application_service::list_users` doc for the split.
let users = auth
.auth_application_service
- .list_users(limit, offset)
+ .list_users_including_external(limit, offset)
.await
.map_err(|e| AppError::internal_error(format!("Failed to list users: {}", e)))?;
|