-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use seperate file for crypto, add Diff Editor, added LICENSE, added R…
…epo URL, slight refactorings
- Loading branch information
Showing
16 changed files
with
1,156 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
/node_modules | ||
|
||
/.storage | ||
/.docu | ||
|
||
.gitignore | ||
README.md |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export default { | ||
scrollBehavior() { | ||
return { top: 0 } | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<template> | ||
<div class="editor" ref="container"></div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import * as monaco from 'monaco-editor'; | ||
let container = ref<HTMLDivElement | null>(null); | ||
let editor: monaco.editor.IStandaloneDiffEditor | null = null; | ||
let modelOriginal: monaco.editor.ITextModel | null = null; | ||
let modelModified: monaco.editor.ITextModel | null = null; | ||
useHead({ | ||
title: 'Franz! Diff' | ||
}); | ||
const emit = defineEmits<{ | ||
(e: "fileChanged"): void, | ||
(e: "inited"): void | ||
}>(); | ||
const props = defineProps<{ | ||
language: string, | ||
original?: string, | ||
modified?: string | ||
}>(); | ||
var ignoreChanges = true; | ||
onMounted(() => { | ||
if (process.client) { | ||
if(!container.value){ | ||
console.error("Container is missing", container.value); | ||
return; | ||
} | ||
editor = monaco.editor.createDiffEditor(container.value!, { | ||
theme: 'vs-dark', | ||
automaticLayout: true, | ||
originalEditable: true | ||
}); | ||
modelOriginal = monaco.editor.createModel(props.original || "", props.language); | ||
modelModified = monaco.editor.createModel(props.modified || "", props.language); | ||
editor.setModel({ | ||
original: modelOriginal!, | ||
modified: modelModified! | ||
}); | ||
editor.onDidChangeModel((_e) => { | ||
if (!ignoreChanges) | ||
emit("fileChanged"); | ||
}); | ||
editor.focus(); | ||
ignoreChanges = false; | ||
emit("inited"); | ||
} | ||
}); | ||
watch(props, (val, old) => { | ||
if (modelOriginal!.getLanguageId() != val.language) { | ||
monaco.editor.setModelLanguage(modelOriginal!, val.language); | ||
monaco.editor.setModelLanguage(modelModified!, val.language); | ||
} | ||
if (val.original && val.original !== old.original) { | ||
ignoreChanges = true; | ||
modelOriginal!.setValue(val.original) | ||
ignoreChanges = false; | ||
} | ||
if (val.modified && val.modified !== old.modified) { | ||
ignoreChanges = true; | ||
modelModified!.setValue(val.modified) | ||
ignoreChanges = false; | ||
} | ||
}); | ||
function getSource(): {original: string, modified: string} { | ||
return { | ||
original: modelOriginal!.getValue(), | ||
modified: modelModified!.getValue() | ||
}; | ||
} | ||
function setSource(original: string, modified: string) { | ||
ignoreChanges = true; | ||
modelOriginal!.setValue(original); | ||
modelModified!.setValue(modified); | ||
ignoreChanges = false; | ||
} | ||
defineExpose({ | ||
getSource, | ||
setSource | ||
}) | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<template> | ||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"> | ||
<path | ||
d="M433.9 129.9l-83.9-83.9A48 48 0 0 0 316.1 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V163.9a48 48 0 0 0 -14.1-33.9zM224 416c-35.3 0-64-28.7-64-64 0-35.3 28.7-64 64-64s64 28.7 64 64c0 35.3-28.7 64-64 64zm96-304.5V212c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12V108c0-6.6 5.4-12 12-12h228.5c3.2 0 6.2 1.3 8.5 3.5l3.5 3.5A12 12 0 0 1 320 111.5z" /> | ||
</svg> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<template> | ||
<a :href="$config.public.repository" target="_blank"> | ||
<button> | ||
v{{ $config.public.version }} | ||
</button> | ||
</a> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export default interface Paste { | ||
id?: string, | ||
content: string, | ||
modified?: string, | ||
language: string, | ||
iv?: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
import type Paste from "./Paste"; | ||
|
||
export async function decryptPaste(key: CryptoKey | string, paste?: Paste): Promise<Paste | null> { | ||
if (!process.client) { | ||
return null; | ||
} | ||
var currentKey: CryptoKey; | ||
const subtle = window.crypto.subtle; | ||
if (typeof key === "string") { | ||
console.log("Key provided as String", key); | ||
currentKey = await decodeJWK(key as string); | ||
console.log("Decoded Key to CryptoKey", currentKey); | ||
} else if (key instanceof CryptoKey) { | ||
currentKey = key; | ||
} else { | ||
throw new Error(`Unsupported Type for argument Key "${typeof key}"`); | ||
} | ||
|
||
if (!paste) { | ||
throw new Error("No Paste provided"); | ||
} | ||
|
||
|
||
if(!paste.iv || !paste.content){ | ||
throw new Error("Malformed Encrypted Paste"); | ||
} | ||
|
||
console.log("Decrypt IV", paste.iv) | ||
const iv = base64ToBytes(paste.iv!); | ||
|
||
const contentCipher = base64ToBytes(paste.content); | ||
const contentDecrypted = await subtle.decrypt({ | ||
name: 'AES-GCM', | ||
iv: iv | ||
}, currentKey, contentCipher); | ||
|
||
const decoder = new TextDecoder(); | ||
const content = decoder.decode(contentDecrypted); | ||
var modified = ""; | ||
if (paste.modified) { | ||
const modifiedCipher = base64ToBytes(paste.modified); | ||
const modifiedDecrypted = await subtle.decrypt({ | ||
name: 'AES-GCM', | ||
iv: iv | ||
}, currentKey, modifiedCipher); | ||
|
||
const modifiedDecoder = new TextDecoder(); | ||
modified = modifiedDecoder.decode(modifiedDecrypted); | ||
} | ||
|
||
const decryptedPaste: Paste = { | ||
id: paste.id, | ||
content: content, | ||
modified: modified, | ||
language: paste.language | ||
}; | ||
return decryptedPaste; | ||
} | ||
|
||
export function extractKeyFromHash(): string | undefined { | ||
const encodedKey = window.location.hash.slice(1); | ||
if (encodedKey !== "") { | ||
return encodedKey; | ||
} | ||
return undefined; | ||
} | ||
|
||
export async function encryptPaste(paste: { id?: string, content: string, modified?: string, language: string }, key?: CryptoKey | string) { | ||
if (!process.client) { | ||
return null; | ||
} | ||
|
||
const subtle = window.crypto.subtle; | ||
|
||
var currentKey: CryptoKey; | ||
if (typeof key === "string") { | ||
currentKey = await decodeJWK(key as string); | ||
} else if (key instanceof CryptoKey) { | ||
currentKey = key; | ||
} else { | ||
currentKey = await generateNewKey(); | ||
} | ||
|
||
const iv = window.crypto.getRandomValues(new Uint8Array(12)); | ||
const base64IV = bytesToBase64(iv); | ||
console.log("Encrypt IV", iv, base64IV); | ||
|
||
const contentEncoder = new TextEncoder(); | ||
const contentEncoded = contentEncoder.encode(paste.content); | ||
const contentCipher = await window.crypto.subtle.encrypt({ | ||
name: 'AES-GCM', | ||
iv: iv, | ||
}, currentKey, contentEncoded); | ||
const contentBase64Encrypted = bytesToBase64(new Uint8Array(contentCipher)); | ||
|
||
|
||
var modifiedBase64Encrypted: string | undefined = undefined; | ||
if (paste.modified) { | ||
const modifiedEncoder = new TextEncoder(); | ||
const modifiedEncoded = modifiedEncoder.encode(paste.modified); | ||
const modifiedCipher = await window.crypto.subtle.encrypt({ | ||
name: 'AES-GCM', | ||
iv: iv, | ||
}, currentKey, modifiedEncoded); | ||
modifiedBase64Encrypted = bytesToBase64(new Uint8Array(modifiedCipher)); | ||
} | ||
|
||
const postBody = { | ||
id: paste.id, | ||
iv: base64IV, | ||
content: contentBase64Encrypted, | ||
modified: modifiedBase64Encrypted, | ||
language: paste.language, | ||
}; | ||
|
||
return postBody; | ||
} | ||
|
||
async function decodeJWK(key: string): Promise<CryptoKey> { | ||
console.log("decodeJwk", key) | ||
const subtle = window.crypto.subtle; | ||
const jwk: JsonWebKey = { | ||
alg: "A256GCM", | ||
ext: true, | ||
k: key, | ||
key_ops: ["encrypt", "decrypt"], | ||
kty: "oct" | ||
} | ||
/* @ts-ignore jwk is unknown or does not match some type */ | ||
return await subtle.importKey("jwk", jwk, { | ||
name: 'AES-GCM' | ||
} as AesKeyAlgorithm, jwk.ext, jwk.key_ops); | ||
} | ||
|
||
async function generateNewKey(): Promise<CryptoKey> { | ||
const subtle = window.crypto.subtle; | ||
const key = await subtle.generateKey({ | ||
name: 'AES-GCM', | ||
length: 256 | ||
}, true, ['encrypt', 'decrypt']); | ||
const jwkOut = await subtle.exportKey('jwk', key); | ||
location.hash = `#${jwkOut.k}`; | ||
return key; | ||
} | ||
|
||
// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem. | ||
export function base64ToBytes(base64: string): Uint8Array { | ||
const binString = atob(base64); | ||
//@ts-ignore fooBar | ||
return Uint8Array.from(binString, (m) => m.codePointAt(0)); | ||
} | ||
|
||
// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem. | ||
export function bytesToBase64(bytes: Uint8Array): string { | ||
const binString = String.fromCodePoint(...bytes); | ||
return btoa(binString); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.