You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
2.7 KiB

(function () {
"use strict";
const storageKey = "teraclone.workspaceTabs.v2";
function allowedPath(path, role) {
// Restore only local page paths, never executable/external URLs or APIs.
if (typeof path !== "string" || !/^\/(?!\/)[A-Za-z0-9/_-]*$/.test(path) ||
/^\/(?:api|static|login|logout)(?:\/|$)/.test(path)) { return false; }
if (role !== "port_operator") { return true; }
return ["/", "/port-status", "/password"].includes(path) ||
/^\/ports\/(?:[1-9]|[1-3][0-9]|4[0-8])\/(?:parameters|operation-1|operation-2|data-log|advanced)$/.test(path);
}
function sanitizeTabs(tabs, role) {
if (!Array.isArray(tabs)) { return []; }
const seen = new Set();
return tabs.reduce(function (result, tab) {
if (!tab || typeof tab.key !== "string" || !tab.key ||
typeof tab.label !== "string" || !tab.label || !allowedPath(tab.path, role)) { return result; }
const match = tab.path.match(/^\/ports\/(\d+)\/(?:parameters|operation-1|operation-2|data-log|advanced)$/);
const normalized = match
? { key: "port-" + Number(match[1]), path: tab.path, label: "포트 " + Number(match[1]) + " 설정" }
: { key: tab.key, path: tab.path, label: tab.label };
if (!seen.has(normalized.key)) { result.push(normalized); seen.add(normalized.key); }
return result;
}, []);
}
function createStore(getStorage, getScope) {
let memory = null;
function matches(record, scope) {
return Boolean(scope.id && record && record.id === scope.id && record.user === scope.user && record.role === scope.role);
}
return {
read: function () {
const scope = getScope();
let record = memory;
try { record = JSON.parse(getStorage().getItem(storageKey) || "null"); }
catch (_) { /* Storage can be disabled; keep this page usable in memory. */ }
return matches(record, scope) ? sanitizeTabs(record.tabs, scope.role) : [];
},
write: function (tabs) {
const scope = getScope();
memory = { id: scope.id, user: scope.user, role: scope.role, tabs: sanitizeTabs(tabs, scope.role) };
try { getStorage().setItem(storageKey, JSON.stringify(memory)); } catch (_) { /* In-memory fallback. */ }
},
clear: function () {
memory = null;
try { getStorage().removeItem(storageKey); } catch (_) { /* Storage unavailable. */ }
}
};
}
const api = { storageKey: storageKey, allowedPath: allowedPath, sanitizeTabs: sanitizeTabs, createStore: createStore };
if (typeof module !== "undefined" && module.exports) { module.exports = api; }
if (typeof window !== "undefined") { window.teraWorkspaceTabs = api; }
}());