Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions admin-ui/src/gql/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,7 @@ export type IMutation = {
/**
* Log the user out of all sessions by invalidating all JWT tokens.
* This increments the token version, making all existing tokens invalid.
* Pass a userId to force-logout another user (requires updateUser permission).
*/
logoutAllSessions?: Maybe<ISuccessResponse>;
/** Make a proposal as answer to the RFP by changing its status to PROCESSED */
Expand Down Expand Up @@ -1627,6 +1628,10 @@ export type IMutationLoginWithWebAuthnArgs = {
webAuthnPublicKeyCredentials: Scalars['JSON']['input'];
};

export type IMutationLogoutAllSessionsArgs = {
userId?: InputMaybe<Scalars['ID']['input']>;
};

export type IMutationMakeQuotationProposalArgs = {
quotationContext?: InputMaybe<Scalars['JSON']['input']>;
quotationId: Scalars['ID']['input'];
Expand Down Expand Up @@ -4931,6 +4936,14 @@ export type ILoginWithWebAuthnMutation = {
loginWithWebAuthn?: { _id: string; tokenExpires: any } | null;
};

export type ILogoutAllSessionsMutationVariables = Exact<{
userId?: InputMaybe<Scalars['ID']['input']>;
}>;

export type ILogoutAllSessionsMutation = {
logoutAllSessions?: { success?: boolean | null } | null;
};

export type IRemoveEmailMutationVariables = Exact<{
email: Scalars['String']['input'];
userId?: InputMaybe<Scalars['ID']['input']>;
Expand Down Expand Up @@ -10098,6 +10111,126 @@ export type IRemoveOrderMutationVariables = Exact<{

export type IRemoveOrderMutation = { removeOrder: { _id: string } };

export type IUserCartQueryVariables = Exact<{
userId?: InputMaybe<Scalars['ID']['input']>;
}>;

export type IUserCartQuery = {
user?: {
_id: string;
cart?: {
_id: string;
status?: IOrderStatus | null;
created?: any | null;
updated?: any | null;
ordered?: any | null;
orderNumber?: string | null;
confirmed?: any | null;
fulfilled?: any | null;
country?: {
_id: string;
isoCode?: string | null;
flagEmoji?: string | null;
} | null;
items?: Array<{
_id: string;
quantity: number;
unitPrice?: { amount: number; currencyCode: string } | null;
total?: { amount: number; currencyCode: string } | null;
product:
| {
_id: string;
texts?: {
_id: string;
slug?: string | null;
title?: string | null;
subtitle?: string | null;
} | null;
media: Array<{
_id: string;
file?: { _id: string; url?: string | null } | null;
}>;
}
| {
_id: string;
texts?: {
_id: string;
slug?: string | null;
title?: string | null;
subtitle?: string | null;
} | null;
media: Array<{
_id: string;
file?: { _id: string; url?: string | null } | null;
}>;
}
| {
_id: string;
texts?: {
_id: string;
slug?: string | null;
title?: string | null;
subtitle?: string | null;
} | null;
media: Array<{
_id: string;
file?: { _id: string; url?: string | null } | null;
}>;
}
| {
_id: string;
texts?: {
_id: string;
slug?: string | null;
title?: string | null;
subtitle?: string | null;
} | null;
media: Array<{
_id: string;
file?: { _id: string; url?: string | null } | null;
}>;
}
| {
_id: string;
texts?: {
_id: string;
slug?: string | null;
title?: string | null;
subtitle?: string | null;
} | null;
media: Array<{
_id: string;
file?: { _id: string; url?: string | null } | null;
}>;
};
}> | null;
contact?: {
telNumber?: string | null;
emailAddress?: string | null;
} | null;
total?: {
isTaxable: boolean;
isNetPrice: boolean;
amount: number;
currencyCode: string;
} | null;
user?: {
_id: string;
username?: string | null;
isGuest: boolean;
avatar?: { _id: string; url?: string | null } | null;
profile?: {
displayName?: string | null;
address?: {
firstName?: string | null;
lastName?: string | null;
} | null;
} | null;
} | null;
} | null;
} | null;
};

export type IUserOrderQueryVariables = Exact<{
userId?: InputMaybe<Scalars['ID']['input']>;
queryString?: InputMaybe<Scalars['String']['input']>;
Expand Down
12 changes: 12 additions & 0 deletions admin-ui/src/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"activate_header_title": "Aktivieren Sie das Abonnement.",
"activated": "Aktiviert",
"active": "Aktiv",
"active_cart": "Aktiver Warenkorb",
"activities": "Aktivitäten",
"adapter": "Adapter",
"add": "Hinzufügen",
Expand Down Expand Up @@ -108,6 +109,8 @@
"cancel": "Abbrechen",
"cart": "Warenkorb",
"cart_created": "Warenkorb erstellt",
"cart_empty": "Warenkorb ist leer",
"cart_last_updated": "Zuletzt aktualisiert {date}",
"categories_count": "Kategorien",
"chain-id": "Chain-ID",
"chain-token-id": "Chain-Token-ID",
Expand Down Expand Up @@ -389,6 +392,9 @@
"filters": "Filter",
"finished": "Beendet",
"first_name": "Vorname",
"force_logout": "Abmeldung erzwingen",
"force_logout_confirmation": "Alle aktiven Sitzungen dieses Benutzers werden ungültig und der Benutzer muss sich erneut anmelden. Fortfahren?",
"force_logout_success": "Alle Sitzungen des Benutzers wurden beendet",
"forget_password": "Passwort vergessen?",
"forgot_password_header_description": "Geben Sie unten Ihre E-Mail-Adresse ein und wir senden Ihnen einen Link zum Zurücksetzen Ihres Passworts!",
"from": "Von",
Expand Down Expand Up @@ -476,6 +482,10 @@
"log_out": "Abmelden",
"login_date_range": "Zuletzt angemeldet",
"login_header": "Anmelden zu Ihrem Konto",
"logout_all_sessions_admin_description": "Alle aktiven Sitzungen dieses Benutzers ungültig machen, zum Beispiel wenn das Konto kompromittiert sein könnte.",
"logout_all_sessions_confirmation": "Sie werden auf diesem und allen anderen Geräten abgemeldet. Fortfahren?",
"logout_all_sessions_own_description": "Von allen Sitzungen auf allen Geräten abmelden, einschließlich dieser.",
"logout_everywhere": "Überall abmelden",
"make-proposal-header": "Angebotserstellung",
"make_leaf": "Zu Blatt machen",
"make_root": "Zu Wurzel machen",
Expand Down Expand Up @@ -724,6 +734,7 @@
"send_reset_link": "Passwort-Zurücksetzungslink senden",
"send_verification_mail": "Send verification mail",
"sequence": "Anzeigereihenfolge",
"sessions": "Sitzungen",
"set_password": "Passwort festlegen",
"setup_complete": "Abgeschlossen",
"setup_now": "Jetzt einrichten",
Expand Down Expand Up @@ -960,6 +971,7 @@
"variation.id": "ID",
"variation.untitled": "Unbetitelte Variation",
"view": "Sicht",
"view_cart": "Warenkorb anzeigen",
"bundle_products": "Pakete",
"chat.error.auth": "🔐 **Authentifizierungsfehler** Ihre Sitzung ist abgelaufen oder das Authentifizierungstoken ist ungültig. *Bitte aktualisieren Sie die Seite oder melden Sie sich erneut an.*",
"chat.error.connection": "🚫 **Verbindungsfehler** Verbindung zum Chat-API-Server unter {chatUrl} nicht möglich. **So aktivieren Sie den Chat:** 1. Starten Sie das Backend. 2. Stellen Sie sicher, dass der Chat-/MCP-Endpunkt konfiguriert ist. 3. Überprüfen Sie NEXT_PUBLIC_CHAT_URL. **Aktuelle Konfiguration:** - Chat-URL: {chatUrl} *Bitte starten Sie das Backend.*",
Expand Down
14 changes: 13 additions & 1 deletion admin-ui/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"activate_header_title": "Activate subscription.",
"activated": "Activated",
"active": "Active",
"active_cart": "Active cart",
"active_types": "Active Worker Types ({count})",
"activities": "Activities",
"adapter": "Adapter",
Expand Down Expand Up @@ -128,7 +129,9 @@
"bundled_items": "Bundled items",
"cancel": "Cancel",
"cart": "Cart",
"cart_created": "Warenkorb erstellt",
"cart_created": "Cart created",
"cart_empty": "Cart is empty",
"cart_last_updated": "Last updated {date}",
"categories_count": "Assortments",
"chain-id": "Chain ID {chainId}",
"chain-token-id": "Token Serial Number",
Expand Down Expand Up @@ -454,6 +457,9 @@
"filters_csv_file": "Filters CSV",
"finished": "Finished",
"first_name": "First name",
"force_logout": "Force logout",
"force_logout_confirmation": "All active sessions of this user will be invalidated and the user will have to sign in again. Continue?",
"force_logout_success": "All sessions of the user have been terminated",
"forget_password": "Forgot your password?",
"forgot_password_header_description": "Enter your email address below and we'll send you a link to reset your password!",
"from": "From",
Expand Down Expand Up @@ -542,6 +548,10 @@
"log_out": "Log out",
"login_date_range": "Login Date Range",
"login_header": "Log in to your account",
"logout_all_sessions_admin_description": "Invalidate all active sessions of this user, for example if the account might be compromised.",
"logout_all_sessions_confirmation": "You will be signed out on this and every other device. Continue?",
"logout_all_sessions_own_description": "Sign out of all sessions on every device, including this one.",
"logout_everywhere": "Log out everywhere",
"make-proposal-header": "Make quotation proposal",
"make_leaf": "Make leaf",
"make_root": "Make root",
Expand Down Expand Up @@ -843,6 +853,7 @@
"send_reset_link": "Send reset link",
"send_verification_mail": "Send verification mail",
"sequence": "Display Order",
"sessions": "Sessions",
"set_password": "Set password",
"setup_complete": "Complete",
"setup_now": "Setup Now",
Expand Down Expand Up @@ -1009,6 +1020,7 @@
"verify_email_token_invalid_error": "The email verification token is either invalid or expired.",
"version": "Version",
"view": "View",
"view_cart": "View cart",
"wallet-address": "Wallet {walletAddress}",
"warehouse": "Warehouse",
"warehouse_detail_title": "Warehouse {id}",
Expand Down
14 changes: 14 additions & 0 deletions admin-ui/src/modules/accounts/components/AccountView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import UserRolesView from './UserRolesView';
import UserTagsView from './UserTagsView';
import UserWebAuthCredentials from './UserWebAuthCredentials';
import Web3Addresses from './Web3Addresses';
import SessionsView from './SessionsView';

const AccountView = ({
_id,
Expand Down Expand Up @@ -157,6 +158,19 @@ const AccountView = ({
</div>
</SelfDocumentingView>
)}

{(currentUser?._id === _id || hasRole(IRoleAction.UpdateUser)) && (
<SelfDocumentingView
documentationLabel={formatMessage({
id: 'sessions',
defaultMessage: 'Sessions',
})}
>
<div className="overflow-hidden rounded-md border-b bg-surface text-text-primary border-border-default px-4 py-5 shadow-sm sm:p-6">
<SessionsView userId={_id} />
</div>
</SelfDocumentingView>
)}
</>
);
};
Expand Down
Loading