add option to randomize keys

This commit is contained in:
marlon-erler
2026-09-30 17:33:53 +02:00
parent 24610af08e
commit c78c5747cf
246 changed files with 20560 additions and 33 deletions
+2
View File
@@ -506,10 +506,12 @@ body[showing-chat] #chat-page-wrapper {
height: var(--ribbon-size);
overflow-x: auto;
padding: 0px;
overflow-y: hidden;
}
#chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar > span {
display: flex;
align-items: center;
overflow-y: hidden;
}
#chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar > span.title {
padding-left: var(--content-padding);
+191 -28
View File
@@ -357,8 +357,7 @@
updateButton: (version) => `Update to ${version}`,
///
typeChat: "chat",
addChatPlaceholder: "Add chat",
addChatButton: "Add chat"
noChatsPlaceholder: "No chats"
},
settings: {
pages: {
@@ -478,6 +477,7 @@
encryptionKeyLabel: "Encryption key",
setEncryptionKeyButtonAudioLabel: "set encryption key",
showEncryptionKey: "Show encryption key",
randomizeKey: "Randomize",
setColorButtonAudioLabel: "set color",
deleteChatButton: "Delete entire chat"
},
@@ -628,8 +628,7 @@
transferDataButton: "Daten \xFCbertragen",
updateButton: (version) => `Aktualisieren: ${version}`,
typeChat: "Chat",
addChatPlaceholder: "Chat hinzuf\xFCgen",
addChatButton: "Chat hinzuf\xFCgen"
noChatsPlaceholder: "Keine Chats"
},
settings: {
pages: {
@@ -743,6 +742,7 @@
encryptionKeyLabel: "Schl\xFCssel",
setEncryptionKeyButtonAudioLabel: "Schl\xFCssel festlegen",
showEncryptionKey: "Schl\xFCssel anzeigen",
randomizeKey: "Zuf\xE4llig generieren",
setColorButtonAudioLabel: "Farbe festlegen",
deleteChatButton: "Gesamten Chat l\xF6schen"
},
@@ -880,8 +880,7 @@
transferDataButton: "Enviar o exportar archivos",
updateButton: (version) => `Actualizar a ${version}`,
typeChat: "chat",
addChatPlaceholder: "A\xF1adir chat",
addChatButton: "A\xF1adir chat"
noChatsPlaceholder: "No hay chats"
},
settings: {
pages: {
@@ -995,6 +994,7 @@
encryptionKeyLabel: "Clave de encriptaci\xF3n",
setEncryptionKeyButtonAudioLabel: "establecer clave de encriptaci\xF3n",
showEncryptionKey: "Mostrar clave de encriptaci\xF3n",
randomizeKey: "Aleatorizar",
setColorButtonAudioLabel: "establecer color",
deleteChatButton: "Eliminar todo el chat"
},
@@ -2966,9 +2966,144 @@
}
};
// node_modules/uint8array-extras/index.js
var objectToString = Object.prototype.toString;
var uint8ArrayStringified = "[object Uint8Array]";
var arrayBufferStringified = "[object ArrayBuffer]";
function isType(value, typeConstructor, typeStringified) {
if (!value) {
return false;
}
if (value.constructor === typeConstructor) {
return true;
}
return objectToString.call(value) === typeStringified;
}
function isUint8Array(value) {
return isType(value, Uint8Array, uint8ArrayStringified);
}
function isArrayBuffer(value) {
return isType(value, ArrayBuffer, arrayBufferStringified);
}
function isUint8ArrayOrArrayBuffer(value) {
return isUint8Array(value) || isArrayBuffer(value);
}
function toUint8ArrayIfArrayBuffer(value) {
return isArrayBuffer(value) ? new Uint8Array(value) : value;
}
function assertUint8ArrayOrArrayBuffer(value) {
if (!isUint8ArrayOrArrayBuffer(value)) {
throw new TypeError(`Expected \`Uint8Array\` or \`ArrayBuffer\`, got \`${typeof value}\``);
}
}
var cachedDecoders = {
utf8: new globalThis.TextDecoder("utf8")
};
var cachedEncoder = new globalThis.TextEncoder();
function base64ToBase64Url(base64) {
return base64.replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
}
var MAX_BLOCK_SIZE = 65535;
function uint8ArrayToBase64(array, { urlSafe = false } = {}) {
assertUint8ArrayOrArrayBuffer(array);
array = toUint8ArrayIfArrayBuffer(array);
let base64 = "";
for (let index = 0; index < array.length; index += MAX_BLOCK_SIZE) {
const chunk = array.subarray(index, index + MAX_BLOCK_SIZE);
base64 += globalThis.btoa(String.fromCodePoint.apply(void 0, chunk));
}
return urlSafe ? base64ToBase64Url(base64) : base64;
}
var byteToHexLookupTable = Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0"));
function uint8ArrayToHex(array) {
assertUint8ArrayOrArrayBuffer(array);
array = toUint8ArrayIfArrayBuffer(array);
let hexString = "";
for (let index = 0; index < array.length; index++) {
hexString += byteToHexLookupTable[array[index]];
}
return hexString;
}
// node_modules/crypto-random-string/index.js
var maxBytesPerRequest = 65536;
var maxCharacterSetSize = 65536;
function fillWithRandomValues(typedArray) {
const maxElementsPerRequest = maxBytesPerRequest / typedArray.BYTES_PER_ELEMENT;
for (let offset = 0; offset < typedArray.length; offset += maxElementsPerRequest) {
crypto.getRandomValues(typedArray.subarray(offset, offset + maxElementsPerRequest));
}
return typedArray;
}
var randomBytes = (byteLength) => fillWithRandomValues(new Uint8Array(byteLength));
var generateForCustomCharacters = (length, characters) => {
const characterCount = characters.length;
const validSelectorCount = Math.floor(maxCharacterSetSize / characterCount) * characterCount;
const entropyLength = Math.ceil(1.1 * length * (maxCharacterSetSize / validSelectorCount));
let string = "";
let stringLength = 0;
while (stringLength < length) {
const entropy = fillWithRandomValues(new Uint16Array(entropyLength));
for (let index = 0; index < entropyLength; index++) {
const entropyValue = entropy[index];
if (entropyValue < validSelectorCount) {
string += characters[entropyValue % characterCount];
stringLength++;
if (stringLength === length) {
return string;
}
}
}
}
return string;
};
var characterSets = /* @__PURE__ */ new Map([
["url-safe", [..."abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"]],
["numeric", [..."0123456789"]],
["distinguishable", [..."CDEHKMPRTUWXY012458"]],
["ascii-printable", [..."!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"]],
["alphanumeric", [..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"]]
]);
var allowedTypes = /* @__PURE__ */ new Set(["hex", "base64", ...characterSets.keys()]);
function cryptoRandomString({ length, type, characters }) {
if (!Number.isSafeInteger(length) || length < 0) {
throw new TypeError("Expected `length` to be a non-negative integer");
}
if (type !== void 0 && characters !== void 0) {
throw new TypeError("Expected either `type` or `characters`");
}
if (characters !== void 0) {
if (typeof characters !== "string") {
throw new TypeError("Expected `characters` to be a string");
}
const customCharacterSet = [...characters];
if (customCharacterSet.length === 0) {
throw new TypeError("Expected `characters` to contain at least 1 character");
}
if (customCharacterSet.length > maxCharacterSetSize) {
throw new TypeError(`Expected \`characters\` to contain at most ${maxCharacterSetSize} characters, got ${customCharacterSet.length}`);
}
return generateForCustomCharacters(length, customCharacterSet);
}
if (type !== void 0 && !allowedTypes.has(type)) {
throw new TypeError(`Unknown type: ${type}`);
}
const characterSet = characterSets.get(type);
if (characterSet !== void 0) {
return generateForCustomCharacters(length, characterSet);
}
if (type === "base64") {
return uint8ArrayToBase64(randomBytes(Math.ceil(length * 0.75))).slice(0, length);
}
return uint8ArrayToHex(randomBytes(Math.ceil(length * 0.5))).slice(0, length);
}
// src/Model/Utility/crypto.ts
var IV_SIZE = 12;
var ENCRYPTION_ALG = "AES-GCM";
function random(length) {
return cryptoRandomString({ length });
}
async function encryptString(plaintext, passphrase) {
if (!window.crypto.subtle) return plaintext;
const iv = generateIV();
@@ -4090,6 +4225,7 @@
};
this.clear = () => {
this.searchInput.value = "";
this.applySearch();
};
this.deleteSuggestion = (suggestion) => {
this.suggestions.remove(suggestion);
@@ -4273,6 +4409,9 @@
const index = this.taskPageViewModel.boardIndexManager.getIndex(this);
this.index.value = index;
};
this.resetPinchZoom = () => {
this.pinchToZoomData.value = { x: 0, y: 0, zoom: 1 };
};
// load
this.preloadData = () => {
this.name.value = this.boardInfo.name;
@@ -4321,27 +4460,6 @@
this.taskPageViewModel.storeLastUsedBoard();
};
this.preloadData();
this.isSelected = createProxyState(
[this.taskPageViewModel.selectedBoardId],
() => this.taskPageViewModel.selectedBoardId.value == this.boardInfo.fileId
);
this.color.subscribe(() => {
if (this.isSelected.value == false) return;
if (this.chatViewModel.selectedPage.value != "tasks" /* Tasks */)
return;
this.applyColor();
});
this.selectedPage.subscribeSilent(() => {
this.storeLastUsedView();
});
boardsAndTasksModel.taskHandlerManager.setHandler(
this.boardInfo.fileId,
(taskFileContent) => {
if (taskFileContent.boardId != this.boardInfo.fileId) return;
this.showTask(taskFileContent);
this.updateTaskIndices();
}
);
this.searchViewModel = new SearchViewModel(
this.taskViewModels,
this.filteredTaskViewModels,
@@ -4357,6 +4475,30 @@
[this.searchViewModel.appliedQuery],
() => this.searchViewModel.appliedQuery.value != ""
);
this.isSelected = createProxyState(
[this.taskPageViewModel.selectedBoardId],
() => this.taskPageViewModel.selectedBoardId.value == this.boardInfo.fileId
);
this.color.subscribe(() => {
if (this.isSelected.value == false) return;
if (this.chatViewModel.selectedPage.value != "tasks" /* Tasks */)
return;
this.applyColor();
});
this.selectedPage.subscribeSilent(() => {
this.storeLastUsedView();
});
this.searchViewModel.appliedQuery.subscribeSilent(() => {
this.resetPinchZoom();
});
boardsAndTasksModel.taskHandlerManager.setHandler(
this.boardInfo.fileId,
(taskFileContent) => {
if (taskFileContent.boardId != this.boardInfo.fileId) return;
this.showTask(taskFileContent);
this.updateTaskIndices();
}
);
this.registerKeyStroke("=" /* Filter */, this.showFilterModal);
this.registerKeyStroke("-" /* Reset */, this.resetFilter);
this.registerKeyStroke("backspace" /* CloseOrCancel */, this.hideFilterModal);
@@ -4598,6 +4740,10 @@
);
this.encryptionKeyInput.callSubscriptions();
};
this.randomizeKey = () => {
this.encryptionKeyInput.value = random(24);
this.setEncryptionKey();
};
this.applyColor = () => {
this.chatViewModel.setColor(this.color.value);
this.appliedColor.value = this.color.value;
@@ -5411,6 +5557,7 @@
// src/View/homePage.tsx
function HomePage(coreViewModel2, storageViewModel2, settingsViewModel2, connectionViewModel2, fileTransferViewModel2, chatListViewModel2) {
const greeting = createProxyState([settingsViewModel2.username], () => coreViewModel2.translations.homePage.greeting(settingsViewModel2.username.value));
const isChatPlaceholderHidden = createProxyState([chatListViewModel2.chatMatches, chatListViewModel2.chatQuery], () => chatListViewModel2.chatMatches.value.size > 0 || chatListViewModel2.chatQuery.value != "");
const overviewSection = /* @__PURE__ */ createElement("div", { id: "overview-section" }, /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "cell_tower"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.homePage.serverAddress), /* @__PURE__ */ createElement(
"input",
{
@@ -5491,6 +5638,13 @@
"on:enter": chatListViewModel2.createChat
}
)), /* @__PURE__ */ createElement("hr", null), NewItemEntry(coreViewModel2, chatListViewModel2.chatQuery, chatListViewModel2.createChat), /* @__PURE__ */ createElement(
"span",
{
class: "secondary",
"toggle:hidden": isChatPlaceholderHidden
},
coreViewModel2.translations.homePage.noChatsPlaceholder
), /* @__PURE__ */ createElement(
"div",
{
id: "chat-grid",
@@ -6303,6 +6457,7 @@
function BoardViewToggleButton(label, icon, page, boardViewModel, key) {
function select() {
boardViewModel.selectedPage.value = page;
boardViewModel.resetPinchZoom();
}
const isSelected = createProxyState(
[boardViewModel.selectedPage],
@@ -6604,7 +6759,15 @@
"on:enter": settingsPageViewModel.setEncryptionKey,
"set:type": settingsPageViewModel.encryptionKeyInputType
}
))), /* @__PURE__ */ createElement("div", { class: "flex-row justify-end width-input" }, /* @__PURE__ */ createElement(
))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
"button",
{
class: "width-50",
"on:click": settingsPageViewModel.randomizeKey
},
coreViewModel2.translations.chatPage.settings.randomizeKey,
/* @__PURE__ */ createElement("span", { class: "icon" }, "shuffle")
), /* @__PURE__ */ createElement(
"button",
{
class: "width-50",
Vendored
+1 -1
View File
@@ -1,4 +1,4 @@
const VERSION = "2610 Beta 21.11"
const VERSION = "2610 Beta 21.12"
function processUrl(event) {
const url = event.request.url;
+1 -1
View File
@@ -1 +1 @@
2610 Beta 21.11
2610 Beta 21.12