Skip to content
Merged
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
11 changes: 10 additions & 1 deletion src/components/ConfigurationTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,16 @@ const ConfigurationTab: React.FC<ConfigurationTabProps> = ({ nodes, channels = [
if (Array.isArray(key)) {
return btoa(String.fromCharCode(...key));
}
return String(key);
// Handle JSON-serialized Uint8Array or other objects with numeric values
if (key && typeof key === 'object') {
try {
const bytes = Object.values(key) as number[];
return btoa(String.fromCharCode(...bytes));
} catch {
// fall through
}
}
return '';
});
setSecurityAdminKeys(keys.length > 0 ? keys : ['']);
}
Expand Down
68 changes: 28 additions & 40 deletions src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,32 @@ let embedOriginsCache: string[] = [];
let embedOriginsCacheTime = 0;
const EMBED_ORIGINS_CACHE_TTL = 60000;

/** Convert protobuf bytes (Uint8Array, Buffer, byte array, or object) to base64 string */
function bytesToBase64(key: any): string {
if (key instanceof Uint8Array || Buffer.isBuffer(key)) {
return Buffer.from(key).toString('base64');
}
if (key && typeof key === 'object' && key.type === 'Buffer' && Array.isArray(key.data)) {
return Buffer.from(key.data).toString('base64');
}
if (Array.isArray(key)) {
return Buffer.from(key).toString('base64');
}
if (typeof key === 'string') {
return key;
}
// Handle generic iterables/objects with byte data (e.g., protobuf Bytes wrappers)
if (key && typeof key === 'object') {
try {
return Buffer.from(Object.values(key) as number[]).toString('base64');
} catch {
// fall through
}
}
logger.warn('Unknown admin key format:', typeof key, key);
return '';
}

function refreshEmbedOriginsCache(): void {
databaseService.embedProfiles.getAllAsync().then(profiles => {
embedOriginsCache = [...new Set(
Expand Down Expand Up @@ -5924,26 +5950,7 @@ apiRouter.post('/admin/load-config', requireAdmin(), async (req, res) => {
// Convert admin keys from Uint8Array to base64 strings for UI
const localAdminKeys = finalConfig.deviceConfig.security.adminKey || [];
config = {
adminKeys: localAdminKeys.map((key: any) => {
if (key instanceof Uint8Array || Buffer.isBuffer(key)) {
return Buffer.from(key).toString('base64');
}
// Handle JSON-serialized Buffer objects (e.g., { type: 'Buffer', data: [...] })
if (key && typeof key === 'object' && key.type === 'Buffer' && Array.isArray(key.data)) {
return Buffer.from(key.data).toString('base64');
}
// Handle array of bytes
if (Array.isArray(key)) {
return Buffer.from(key).toString('base64');
}
// Already a string (base64)
if (typeof key === 'string') {
return key;
}
// Fallback - try to convert
logger.warn('Unknown admin key format:', typeof key, key);
return String(key);
}),
adminKeys: localAdminKeys.map((key: any) => bytesToBase64(key)),
isManaged: finalConfig.deviceConfig.security.isManaged,
serialEnabled: finalConfig.deviceConfig.security.serialEnabled,
debugLogApiEnabled: finalConfig.deviceConfig.security.debugLogApiEnabled,
Expand Down Expand Up @@ -6135,26 +6142,7 @@ apiRouter.post('/admin/load-config', requireAdmin(), async (req, res) => {
// Convert admin keys from Uint8Array to base64 strings for UI
const remoteAdminKeys = remoteConfig.adminKey || [];
config = {
adminKeys: remoteAdminKeys.map((key: any) => {
if (key instanceof Uint8Array || Buffer.isBuffer(key)) {
return Buffer.from(key).toString('base64');
}
// Handle JSON-serialized Buffer objects (e.g., { type: 'Buffer', data: [...] })
if (key && typeof key === 'object' && key.type === 'Buffer' && Array.isArray(key.data)) {
return Buffer.from(key.data).toString('base64');
}
// Handle array of bytes
if (Array.isArray(key)) {
return Buffer.from(key).toString('base64');
}
// Already a string (base64)
if (typeof key === 'string') {
return key;
}
// Fallback - try to convert
logger.warn('Unknown admin key format:', typeof key, key);
return String(key);
}),
adminKeys: remoteAdminKeys.map((key: any) => bytesToBase64(key)),
isManaged: remoteConfig.isManaged,
serialEnabled: remoteConfig.serialEnabled,
debugLogApiEnabled: remoteConfig.debugLogApiEnabled,
Expand Down
Loading