Ensure non multi-user flow stays
This commit is contained in:
@@ -7,6 +7,7 @@ import { ConfirmModal } from './ConfirmModal';
|
||||
import { Logo } from './Logo';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
import { readImpersonationState, stopImpersonation as restoreImpersonation, type ImpersonationState } from '../utils/impersonation';
|
||||
import { getInitialsFromName } from '../utils/user';
|
||||
|
||||
interface SidebarProps {
|
||||
collections: Collection[];
|
||||
@@ -111,18 +112,6 @@ const SidebarItem: React.FC<SidebarItemProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const getInitialsFromName = (name: string): string => {
|
||||
const trimmed = name.trim();
|
||||
if (!trimmed) return 'U';
|
||||
const parts = trimmed.split(/\s+/).filter(Boolean);
|
||||
if (parts.length >= 2) {
|
||||
return `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase();
|
||||
}
|
||||
return trimmed.slice(0, 2).toUpperCase();
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const Sidebar: React.FC<SidebarProps> = ({
|
||||
collections,
|
||||
selectedCollectionId,
|
||||
|
||||
@@ -62,15 +62,7 @@ export const UIOptions = {
|
||||
},
|
||||
};
|
||||
|
||||
export const getInitialsFromName = (name: string): string => {
|
||||
const trimmed = name.trim();
|
||||
if (!trimmed) return 'U';
|
||||
const parts = trimmed.split(/\s+/).filter(Boolean);
|
||||
if (parts.length >= 2) {
|
||||
return `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase();
|
||||
}
|
||||
return trimmed.slice(0, 2).toUpperCase();
|
||||
};
|
||||
export { getInitialsFromName } from "../../utils/user";
|
||||
|
||||
export const getColorFromString = (str: string): string => {
|
||||
const COLORS = [
|
||||
|
||||
@@ -106,7 +106,13 @@ const getSecureRandomInt = (maxExclusive: number): number => {
|
||||
cryptoObj.getRandomValues(buffer);
|
||||
return buffer[0] % maxExclusive;
|
||||
}
|
||||
const seed = `${Date.now().toString(16)}:${performance.now().toString(16)}`;
|
||||
const perfNow =
|
||||
typeof globalThis !== "undefined" &&
|
||||
typeof globalThis.performance !== "undefined" &&
|
||||
typeof globalThis.performance.now === "function"
|
||||
? globalThis.performance.now()
|
||||
: 0;
|
||||
const seed = `${Date.now().toString(16)}:${perfNow.toString(16)}`;
|
||||
return hashString(seed) % maxExclusive;
|
||||
};
|
||||
|
||||
@@ -129,7 +135,13 @@ const generateClientId = (): string => {
|
||||
}
|
||||
|
||||
// Final fallback for very old browsers; uniqueness window-scoped only.
|
||||
const entropy = `${Date.now().toString(16)}-${performance.now().toString(16)}-${getSecureRandomInt(1_000_000_000).toString(16)}`;
|
||||
const perfNow =
|
||||
typeof globalThis !== "undefined" &&
|
||||
typeof globalThis.performance !== "undefined" &&
|
||||
typeof globalThis.performance.now === "function"
|
||||
? globalThis.performance.now()
|
||||
: 0;
|
||||
const entropy = `${Date.now().toString(16)}-${perfNow.toString(16)}-${getSecureRandomInt(1_000_000_000).toString(16)}`;
|
||||
return `id-${hashString(entropy).toString(16)}-${hashString(`${entropy}:2`).toString(16)}`;
|
||||
};
|
||||
|
||||
@@ -152,12 +164,30 @@ export const getFingerprintInitials = (seed?: string): string => {
|
||||
export const getUserIdentity = (): UserIdentity => {
|
||||
const stored = localStorage.getItem("excalidash-user-id");
|
||||
if (stored) {
|
||||
const parsed = JSON.parse(stored) as UserIdentity;
|
||||
if (!parsed.initials || parsed.initials.length !== 2) {
|
||||
parsed.initials = getFingerprintInitials(parsed.id);
|
||||
localStorage.setItem("excalidash-user-id", JSON.stringify(parsed));
|
||||
try {
|
||||
const parsed = JSON.parse(stored) as Partial<UserIdentity>;
|
||||
if (
|
||||
parsed &&
|
||||
typeof parsed === "object" &&
|
||||
typeof parsed.id === "string" &&
|
||||
typeof parsed.name === "string" &&
|
||||
typeof parsed.color === "string"
|
||||
) {
|
||||
const normalized: UserIdentity = {
|
||||
id: parsed.id,
|
||||
name: parsed.name,
|
||||
color: parsed.color,
|
||||
initials:
|
||||
typeof parsed.initials === "string" && parsed.initials.length === 2
|
||||
? parsed.initials
|
||||
: getFingerprintInitials(parsed.id),
|
||||
};
|
||||
localStorage.setItem("excalidash-user-id", JSON.stringify(normalized));
|
||||
return normalized;
|
||||
}
|
||||
} catch {
|
||||
// Fall through to regenerate identity.
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
const deviceId = getOrCreateBrowserFingerprint();
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
export const getInitialsFromName = (name: string): string => {
|
||||
const trimmed = name.trim();
|
||||
if (!trimmed) return "U";
|
||||
const parts = trimmed.split(/\s+/).filter(Boolean);
|
||||
if (parts.length >= 2) {
|
||||
return `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase();
|
||||
}
|
||||
return trimmed.slice(0, 2).toUpperCase();
|
||||
};
|
||||
Reference in New Issue
Block a user